234 lines
8.7 KiB
JavaScript
234 lines
8.7 KiB
JavaScript
import { createVNode as _createVNode, mergeProps as _mergeProps, Fragment as _Fragment } from "vue";
|
|
// Components
|
|
import { VDataTableColumn } from "./VDataTableColumn.mjs";
|
|
import { VCheckboxBtn } from "../VCheckbox/index.mjs";
|
|
import { VChip } from "../VChip/index.mjs";
|
|
import { VIcon } from "../VIcon/index.mjs";
|
|
import { VSelect } from "../VSelect/index.mjs"; // Composables
|
|
import { useHeaders } from "./composables/headers.mjs";
|
|
import { useSelection } from "./composables/select.mjs";
|
|
import { useSort } from "./composables/sort.mjs";
|
|
import { useBackgroundColor } from "../../composables/color.mjs";
|
|
import { makeDisplayProps, useDisplay } from "../../composables/display.mjs";
|
|
import { IconValue } from "../../composables/icons.mjs";
|
|
import { LoaderSlot, makeLoaderProps, useLoader } from "../../composables/loader.mjs";
|
|
import { useLocale } from "../../composables/locale.mjs"; // Utilities
|
|
import { computed, mergeProps } from 'vue';
|
|
import { convertToUnit, genericComponent, propsFactory, useRender } from "../../util/index.mjs"; // Types
|
|
export const makeVDataTableHeadersProps = propsFactory({
|
|
color: String,
|
|
disableSort: Boolean,
|
|
fixedHeader: Boolean,
|
|
multiSort: Boolean,
|
|
sortAscIcon: {
|
|
type: IconValue,
|
|
default: '$sortAsc'
|
|
},
|
|
sortDescIcon: {
|
|
type: IconValue,
|
|
default: '$sortDesc'
|
|
},
|
|
headerProps: {
|
|
type: Object
|
|
},
|
|
/** @deprecated */
|
|
sticky: Boolean,
|
|
...makeDisplayProps(),
|
|
...makeLoaderProps()
|
|
}, 'VDataTableHeaders');
|
|
export const VDataTableHeaders = genericComponent()({
|
|
name: 'VDataTableHeaders',
|
|
props: makeVDataTableHeadersProps(),
|
|
setup(props, _ref) {
|
|
let {
|
|
slots
|
|
} = _ref;
|
|
const {
|
|
t
|
|
} = useLocale();
|
|
const {
|
|
toggleSort,
|
|
sortBy,
|
|
isSorted
|
|
} = useSort();
|
|
const {
|
|
someSelected,
|
|
allSelected,
|
|
selectAll,
|
|
showSelectAll
|
|
} = useSelection();
|
|
const {
|
|
columns,
|
|
headers
|
|
} = useHeaders();
|
|
const {
|
|
loaderClasses
|
|
} = useLoader(props);
|
|
function getFixedStyles(column, y) {
|
|
if (!(props.sticky || props.fixedHeader) && !column.fixed) return undefined;
|
|
return {
|
|
position: 'sticky',
|
|
left: column.fixed ? convertToUnit(column.fixedOffset) : undefined,
|
|
top: props.sticky || props.fixedHeader ? `calc(var(--v-table-header-height) * ${y})` : undefined
|
|
};
|
|
}
|
|
function getSortIcon(column) {
|
|
const item = sortBy.value.find(item => item.key === column.key);
|
|
if (!item) return props.sortAscIcon;
|
|
return item.order === 'asc' ? props.sortAscIcon : props.sortDescIcon;
|
|
}
|
|
const {
|
|
backgroundColorClasses,
|
|
backgroundColorStyles
|
|
} = useBackgroundColor(props, 'color');
|
|
const {
|
|
displayClasses,
|
|
mobile
|
|
} = useDisplay(props);
|
|
const slotProps = computed(() => ({
|
|
headers: headers.value,
|
|
columns: columns.value,
|
|
toggleSort,
|
|
isSorted,
|
|
sortBy: sortBy.value,
|
|
someSelected: someSelected.value,
|
|
allSelected: allSelected.value,
|
|
selectAll,
|
|
getSortIcon
|
|
}));
|
|
const headerCellClasses = computed(() => ['v-data-table__th', {
|
|
'v-data-table__th--sticky': props.sticky || props.fixedHeader
|
|
}, displayClasses.value, loaderClasses.value]);
|
|
const VDataTableHeaderCell = _ref2 => {
|
|
let {
|
|
column,
|
|
x,
|
|
y
|
|
} = _ref2;
|
|
const noPadding = column.key === 'data-table-select' || column.key === 'data-table-expand';
|
|
const headerProps = mergeProps(props.headerProps ?? {}, column.headerProps ?? {});
|
|
return _createVNode(VDataTableColumn, _mergeProps({
|
|
"tag": "th",
|
|
"align": column.align,
|
|
"class": [{
|
|
'v-data-table__th--sortable': column.sortable && !props.disableSort,
|
|
'v-data-table__th--sorted': isSorted(column),
|
|
'v-data-table__th--fixed': column.fixed
|
|
}, ...headerCellClasses.value],
|
|
"style": {
|
|
width: convertToUnit(column.width),
|
|
minWidth: convertToUnit(column.minWidth),
|
|
maxWidth: convertToUnit(column.maxWidth),
|
|
...getFixedStyles(column, y)
|
|
},
|
|
"colspan": column.colspan,
|
|
"rowspan": column.rowspan,
|
|
"onClick": column.sortable ? () => toggleSort(column) : undefined,
|
|
"fixed": column.fixed,
|
|
"nowrap": column.nowrap,
|
|
"lastFixed": column.lastFixed,
|
|
"noPadding": noPadding
|
|
}, headerProps), {
|
|
default: () => {
|
|
const columnSlotName = `header.${column.key}`;
|
|
const columnSlotProps = {
|
|
column,
|
|
selectAll,
|
|
isSorted,
|
|
toggleSort,
|
|
sortBy: sortBy.value,
|
|
someSelected: someSelected.value,
|
|
allSelected: allSelected.value,
|
|
getSortIcon
|
|
};
|
|
if (slots[columnSlotName]) return slots[columnSlotName](columnSlotProps);
|
|
if (column.key === 'data-table-select') {
|
|
return slots['header.data-table-select']?.(columnSlotProps) ?? (showSelectAll.value && _createVNode(VCheckboxBtn, {
|
|
"modelValue": allSelected.value,
|
|
"indeterminate": someSelected.value && !allSelected.value,
|
|
"onUpdate:modelValue": selectAll
|
|
}, null));
|
|
}
|
|
return _createVNode("div", {
|
|
"class": "v-data-table-header__content"
|
|
}, [_createVNode("span", null, [column.title]), column.sortable && !props.disableSort && _createVNode(VIcon, {
|
|
"key": "icon",
|
|
"class": "v-data-table-header__sort-icon",
|
|
"icon": getSortIcon(column)
|
|
}, null), props.multiSort && isSorted(column) && _createVNode("div", {
|
|
"key": "badge",
|
|
"class": ['v-data-table-header__sort-badge', ...backgroundColorClasses.value],
|
|
"style": backgroundColorStyles.value
|
|
}, [sortBy.value.findIndex(x => x.key === column.key) + 1])]);
|
|
}
|
|
});
|
|
};
|
|
const VDataTableMobileHeaderCell = () => {
|
|
const headerProps = mergeProps(props.headerProps ?? {} ?? {});
|
|
const displayItems = computed(() => {
|
|
return columns.value.filter(column => column?.sortable && !props.disableSort);
|
|
});
|
|
const appendIcon = computed(() => {
|
|
const showSelectColumn = columns.value.find(column => column.key === 'data-table-select');
|
|
if (showSelectColumn == null) return;
|
|
return allSelected.value ? '$checkboxOn' : someSelected.value ? '$checkboxIndeterminate' : '$checkboxOff';
|
|
});
|
|
return _createVNode(VDataTableColumn, _mergeProps({
|
|
"tag": "th",
|
|
"class": [...headerCellClasses.value],
|
|
"colspan": headers.value.length + 1
|
|
}, headerProps), {
|
|
default: () => [_createVNode("div", {
|
|
"class": "v-data-table-header__content"
|
|
}, [_createVNode(VSelect, {
|
|
"chips": true,
|
|
"class": "v-data-table__td-sort-select",
|
|
"clearable": true,
|
|
"density": "default",
|
|
"items": displayItems.value,
|
|
"label": t('$vuetify.dataTable.sortBy'),
|
|
"multiple": props.multiSort,
|
|
"variant": "underlined",
|
|
"onClick:clear": () => sortBy.value = [],
|
|
"appendIcon": appendIcon.value,
|
|
"onClick:append": () => selectAll(!allSelected.value)
|
|
}, {
|
|
...slots,
|
|
chip: props => _createVNode(VChip, {
|
|
"onClick": props.item.raw?.sortable ? () => toggleSort(props.item.raw) : undefined,
|
|
"onMousedown": e => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
}
|
|
}, {
|
|
default: () => [props.item.title, _createVNode(VIcon, {
|
|
"class": ['v-data-table__td-sort-icon', isSorted(props.item.raw) && 'v-data-table__td-sort-icon-active'],
|
|
"icon": getSortIcon(props.item.raw),
|
|
"size": "small"
|
|
}, null)]
|
|
})
|
|
})])]
|
|
});
|
|
};
|
|
useRender(() => {
|
|
return mobile.value ? _createVNode("tr", null, [_createVNode(VDataTableMobileHeaderCell, null, null)]) : _createVNode(_Fragment, null, [slots.headers ? slots.headers(slotProps.value) : headers.value.map((row, y) => _createVNode("tr", null, [row.map((column, x) => _createVNode(VDataTableHeaderCell, {
|
|
"column": column,
|
|
"x": x,
|
|
"y": y
|
|
}, null))])), props.loading && _createVNode("tr", {
|
|
"class": "v-data-table-progress"
|
|
}, [_createVNode("th", {
|
|
"colspan": columns.value.length
|
|
}, [_createVNode(LoaderSlot, {
|
|
"name": "v-data-table-progress",
|
|
"absolute": true,
|
|
"active": true,
|
|
"color": typeof props.loading === 'boolean' ? undefined : props.loading,
|
|
"indeterminate": true
|
|
}, {
|
|
default: slots.loader
|
|
})])])]);
|
|
});
|
|
}
|
|
});
|
|
//# sourceMappingURL=VDataTableHeaders.mjs.map
|