UNPKG

@oruga-ui/oruga-next

Version:

UI components for Vue.js and CSS framework agnostic

1,150 lines (1,149 loc) 67.8 kB
"use strict"; /*! Oruga v0.11.0 | MIT License | github.com/oruga-ui/oruga */ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } }); const vue = require("vue"); const Checkbox_vue_vue_type_script_setup_true_lang = require("./Checkbox.vue_vue_type_script_setup_true_lang-yO2Pr_hR.cjs"); const Icon_vue_vue_type_script_setup_true_lang = require("./Icon.vue_vue_type_script_setup_true_lang-ZtEqoTvT.cjs"); const Input_vue_vue_type_script_setup_true_lang = require("./Input.vue_vue_type_script_setup_true_lang-YK7-bzmD.cjs"); const Loading_vue_vue_type_script_setup_true_lang = require("./Loading.vue_vue_type_script_setup_true_lang-D-rFtctf.cjs"); const SlotComponent = require("./SlotComponent-BMmH3QFp.cjs"); const Button_vue_vue_type_script_setup_true_lang = require("./Button.vue_vue_type_script_setup_true_lang-BSST4v3C.cjs"); const Select_vue_vue_type_script_setup_true_lang = require("./Select.vue_vue_type_script_setup_true_lang-BYneGxD5.cjs"); const Field_vue_vue_type_script_setup_true_lang = require("./Field.vue_vue_type_script_setup_true_lang-DnrmwKev.cjs"); const defineClasses = require("./defineClasses-Cqhbv-UT.cjs"); const useParentProvider = require("./useParentProvider-CPNahRzD.cjs"); const helpers = require("./helpers.cjs"); const Pagination_vue_vue_type_script_setup_true_lang = require("./Pagination.vue_vue_type_script_setup_true_lang-BNFebxAT.cjs"); const config = require("./config-eYBvpFOZ.cjs"); const useMatchMedia = require("./useMatchMedia-EgWTgaUx.cjs"); const useDebounce = require("./useDebounce-BAemuDpF.cjs"); const useOptions = require("./useOptions-YcqJ438a.cjs"); const useSequentialId = require("./useSequentialId-BnH6otip.cjs"); const _hoisted_1$2 = ["value"]; const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({ ...{ isOruga: true, name: "OTableMobileSort", configField: "table" }, __name: "TableMobileSort", props: { currentSortColumn: { type: Object, default: void 0 }, columns: { type: Array, default: void 0 }, placeholder: { type: String, default: void 0 }, iconPack: { type: String, default: void 0 }, sortIcon: { type: String, default: "arrow-up" }, sortIconSize: { type: String, default: "small" }, isAsc: { type: Boolean, default: false }, mobileSortClasses: { type: Array, required: true } }, emits: ["sort"], setup(__props, { emit: __emit }) { var _a; const props = __props; const emits = __emit; const mobileSort = vue.ref((_a = props.currentSortColumn) == null ? void 0 : _a.identifier); const showPlaceholder = vue.computed( () => !props.columns || props.columns.every((column) => column.identifier !== mobileSort.value) ); const sortableColumns = vue.computed( () => props.columns ? props.columns.filter((c) => c.sortable) : [] ); const isCurrentSort = vue.computed( () => { var _a2; return ((_a2 = props.currentSortColumn) == null ? void 0 : _a2.identifier) === mobileSort.value; } ); vue.watch(mobileSort, (value) => { var _a2; if (((_a2 = props.currentSortColumn) == null ? void 0 : _a2.identifier) === value) return; sort(new Event("sort")); }); vue.watch( () => props.currentSortColumn, (column) => { mobileSort.value = column == null ? void 0 : column.identifier; } ); function sort(event) { const column = sortableColumns.value.find( (column2) => column2.identifier === mobileSort.value ); if (!column) return; emits("sort", column, event); } return (_ctx, _cache) => { return vue.openBlock(), vue.createElementBlock("div", { class: vue.normalizeClass(__props.mobileSortClasses) }, [ vue.createVNode(Field_vue_vue_type_script_setup_true_lang._sfc_main, { addons: "" }, { default: vue.withCtx(() => [ vue.createVNode(Select_vue_vue_type_script_setup_true_lang._sfc_main, { modelValue: mobileSort.value, "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => mobileSort.value = $event), expanded: "" }, { default: vue.withCtx(() => [ __props.placeholder ? vue.withDirectives((vue.openBlock(), vue.createElementBlock("option", { key: 0, value: {}, selected: "", disabled: "", hidden: "" }, vue.toDisplayString(__props.placeholder), 513)), [ [vue.vShow, showPlaceholder.value] ]) : vue.createCommentVNode("", true), (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(sortableColumns.value, (column, index2) => { return vue.openBlock(), vue.createElementBlock("option", { key: column.field || index2, value: column.identifier }, vue.toDisplayString(column.label), 9, _hoisted_1$2); }), 128)) ]), _: 1 }, 8, ["modelValue"]), vue.createVNode(Button_vue_vue_type_script_setup_true_lang._sfc_main, { onClick: _cache[1] || (_cache[1] = ($event) => sort($event)) }, { default: vue.withCtx(() => [ vue.withDirectives(vue.createVNode(Icon_vue_vue_type_script_setup_true_lang._sfc_main, { icon: __props.sortIcon, pack: __props.iconPack, size: __props.sortIconSize, rotation: !__props.isAsc ? 180 : 0 }, null, 8, ["icon", "pack", "size", "rotation"]), [ [vue.vShow, isCurrentSort.value] ]) ]), _: 1 }) ]), _: 1 }) ], 2); }; } }); const _hoisted_1$1 = ["data-id"]; const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({ ...{ isOruga: true, name: "OTableColumn", configField: "table" }, __name: "TableColumn", props: { label: { default: void 0 }, field: { default: void 0 }, formatter: { type: Function, default: void 0 }, subheading: { default: void 0 }, width: { default: void 0 }, numeric: { type: Boolean, default: false }, position: { default: void 0 }, searchable: { type: Boolean, default: false }, sortable: { type: Boolean, default: false }, hidden: { type: Boolean, default: false }, sticky: { type: Boolean, default: false }, headerSelectable: { type: Boolean, default: false }, customSort: { type: Function, default: void 0 }, customSearch: { type: Function, default: void 0 }, thAttrs: { default: void 0 }, tdAttrs: { default: void 0 } }, setup(__props) { const props = __props; const style = vue.computed(() => ({ width: helpers.toCssDimension(props.width) })); const isHeaderUnselectable = vue.computed( () => !props.headerSelectable && props.sortable ); const vm = vue.getCurrentInstance(); const providedData = vue.computed(() => ({ ...props, $el: vm.proxy, $slots: vm.slots, style: style.value, thClasses: thClasses.value, tdClasses: tdClasses.value })); const { parent, item } = useParentProvider.useProviderChild({ data: providedData }); const thClasses = defineClasses.defineClasses( [ "thCurrentSortClass", "o-table__th-current-sort", null, vue.computed(() => { var _a; return (_a = parent.value) == null ? void 0 : _a.isColumnSorted(item.value); }) ], [ "thSortableClass", "o-table__th--sortable", null, vue.computed(() => props.sortable) ], [ "thUnselectableClass", "o-table__th--unselectable", null, isHeaderUnselectable ], [ "thPositionClass", "o-table__th--", vue.computed(() => props.position), vue.computed(() => !!props.position) ], [ "thStickyClass", "o-table__th--sticky", null, vue.computed(() => props.sticky) ] ); const tdClasses = defineClasses.defineClasses( [ "tdPositionClass", "o-table__td--", vue.computed(() => props.position), vue.computed(() => !!props.position) ], [ "tdStickyClass", "o-table__td--sticky", null, vue.computed(() => props.sticky) ] ); return (_ctx, _cache) => { return vue.openBlock(), vue.createElementBlock("span", { "data-oruga": "table-column", "data-id": `table-${vue.unref(item).identifier}` }, [ vue.createTextVNode(vue.toDisplayString(_ctx.label) + " ", 1), vue.createCommentVNode("", true) ], 8, _hoisted_1$1); }; } }); const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({ ...{ isOruga: true, name: "OTablePagination", configField: "table", inheritAttrs: false }, __name: "TablePagination", props: /* @__PURE__ */ vue.mergeModels({ current: { type: Number, default: void 0 }, paginated: { type: Boolean, default: false }, rootClass: { type: [String, Array, Object], default: void 0 } }, { "current": {}, "currentModifiers": {} }), emits: /* @__PURE__ */ vue.mergeModels(["update:current", "change"], ["update:current"]), setup(__props, { emit: __emit }) { const emits = __emit; const currentPage = vue.useModel(__props, "current"); function pageChanged(page) { const newPage = page > 0 ? page : 1; currentPage.value = newPage; emits("change", newPage); } return (_ctx, _cache) => { return vue.openBlock(), vue.createElementBlock("div", { class: vue.normalizeClass(__props.rootClass) }, [ vue.createElementVNode("div", null, [ vue.renderSlot(_ctx.$slots, "default") ]), vue.createElementVNode("div", null, [ __props.paginated ? (vue.openBlock(), vue.createBlock(Pagination_vue_vue_type_script_setup_true_lang._sfc_main, vue.mergeProps({ key: 0 }, _ctx.$attrs, { current: currentPage.value, onChange: pageChanged }), null, 16, ["current"])) : vue.createCommentVNode("", true) ]) ], 2); }; } }); const _hoisted_1 = { ref: "slotsWrapper", style: { "display": "none" } }; const _hoisted_2 = ["tabindex", "aria-rowcount", "aria-colcount"]; const _hoisted_3 = { key: 0 }; const _hoisted_4 = { key: 1 }; const _hoisted_5 = { "aria-rowindex": 1 }; const _hoisted_6 = ["aria-colindex"]; const _hoisted_7 = ["draggable", "aria-sort", "aria-colindex", "onClick", "onDragstart", "onDragend", "onDrop", "onDragover", "onDragleave"]; const _hoisted_8 = { key: 1 }; const _hoisted_9 = ["aria-hidden"]; const _hoisted_10 = ["aria-colindex"]; const _hoisted_11 = { key: 0, "aria-rowindex": 2 }; const _hoisted_12 = { key: 1 }; const _hoisted_13 = { key: 2 }; const _hoisted_14 = ["aria-rowindex"]; const _hoisted_15 = { key: 1 }; const _hoisted_16 = { key: 1 }; const _hoisted_17 = { key: 2 }; const _hoisted_18 = ["draggable", "aria-rowindex", "onClick", "onDblclick", "onMouseenter", "onMouseleave", "onContextmenu", "onDragstart", "onDragend", "onDrop", "onDragover", "onDragleave"]; const _hoisted_19 = ["colspan"]; const _hoisted_20 = ["colspan"]; const _hoisted_21 = { key: 2 }; const _hoisted_22 = ["colspan"]; const _sfc_main = /* @__PURE__ */ vue.defineComponent({ ...{ isOruga: true, name: "OTable", configField: "table", inheritAttrs: false }, __name: "Table", props: /* @__PURE__ */ vue.mergeModels({ override: { type: Boolean, default: void 0 }, data: { default: void 0 }, columns: { default: void 0 }, rowKey: { default: () => config.getDefault("table.rowKey") }, rowClass: { type: Function, default: config.getDefault("table.rowClass", () => "") }, thAttrs: { type: Function, default: void 0 }, tdAttrs: { type: Function, default: void 0 }, customCompare: { type: Function, default: void 0 }, bordered: { type: Boolean, default: () => config.getDefault("table.bordered", false) }, striped: { type: Boolean, default: () => config.getDefault("table.striped", false) }, narrowed: { type: Boolean, default: () => config.getDefault("table.narrowed", false) }, hoverable: { type: Boolean, default: () => config.getDefault("table.hoverable", false) }, selected: { default: void 0 }, selectable: { type: Boolean, default: () => config.getDefault("table.selectable", false) }, isRowSelectable: { type: Function, default: () => true }, showHeader: { type: Boolean, default: () => config.getDefault("table.showHeader", true) }, draggable: { type: Boolean, default: false }, draggableColumn: { type: Boolean, default: false }, scrollable: { type: Boolean, default: void 0 }, stickyHeader: { type: Boolean, default: false }, height: { default: void 0 }, checkable: { type: Boolean, default: false }, checkableHeader: { type: Boolean, default: true }, stickyCheckbox: { type: Boolean, default: false }, checkedRows: { default: () => [] }, checkboxPosition: { default: () => config.getDefault("table.checkboxPosition", "left") }, checkboxVariant: { default: () => config.getDefault("table.checkboxVariant") }, isRowChecked: { type: Function, default: void 0 }, isRowCheckable: { type: Function, default: config.getDefault("table.isRowCheckable", () => true) }, backendSorting: { type: Boolean, default: () => config.getDefault("table.backendSorting", false) }, defaultSort: { default: () => config.getDefault("table.defaultSort") }, defaultSortDirection: { default: () => config.getDefault("table.defaultSortDirection", "asc") }, sortIcon: { default: () => config.getDefault("table.sortIcon", "arrow-up") }, sortIconSize: { default: () => config.getDefault("table.sortIconSize", "small") }, iconPack: { default: () => config.getDefault("table.iconPack") }, detailed: { type: Boolean, default: false }, detailedRows: { default: () => [] }, isDetailedVisible: { type: Function, default: config.getDefault("table.isDetailedVisible", () => true) }, showDetailIcon: { type: Boolean, default: () => config.getDefault("table.showDetailIcon", true) }, detailIcon: { default: () => config.getDefault("table.detailIcon", "chevron-right") }, customDetailRow: { type: Boolean, default: false }, detailTransition: { default: () => config.getDefault("table.detailTransition", "slide") }, paginated: { type: Boolean, default: () => config.getDefault("table.paginated", false) }, backendPagination: { type: Boolean, default: false }, total: { default: 0 }, currentPage: { default: 1 }, perPage: { default: () => config.getDefault("table.perPage", 20) }, paginationPosition: { default: () => config.getDefault("table.paginationPosition", "bottom") }, paginationSize: { default: () => config.getDefault("table.paginationSize", "small") }, paginationRounded: { type: Boolean, default: () => config.getDefault("table.paginationRounded", false) }, paginationSimple: { type: Boolean, default: () => config.getDefault("table.paginationSimple", false) }, paginationRangeBefore: { default: void 0 }, paginationRangeAfter: { default: void 0 }, paginationOrder: { default: () => config.getDefault("table.paginationOrder") }, backendFiltering: { type: Boolean, default: () => config.getDefault("table.backendFiltering", false) }, filtersIcon: { default: () => config.getDefault("table.filterIcon") }, filtersPlaceholder: { default: () => config.getDefault("table.filterPlaceholder") }, filtersEvent: { default: "" }, filterDebounce: { default: () => config.getDefault("table.filterDebounce", 300) }, emptyLabel: { default: () => config.getDefault("table.emptyLabel") }, emptyIcon: { default: () => config.getDefault("table.emptyIcon") }, emptyIconSize: { default: () => config.getDefault("table.emptyIconSize") }, loading: { type: Boolean, default: false }, loadingIcon: { default: () => config.getDefault("table.loadingIcon", "loading") }, loadingLabel: { default: () => config.getDefault("table.loadingLabel") }, mobileBreakpoint: { default: () => config.getDefault("table.mobileBreakpoint") }, mobileCards: { type: Boolean, default: () => config.getDefault("table.mobileCards", true) }, mobileSortPlaceholder: { default: () => config.getDefault("table.mobileSortPlaceholder") }, ariaNextLabel: { default: () => config.getDefault("table.ariaNextLabel") }, ariaPreviousLabel: { default: () => config.getDefault("table.ariaPreviousLabel") }, ariaPageLabel: { default: () => config.getDefault("table.ariaPageLabel") }, ariaCurrentLabel: { default: () => config.getDefault("table.ariaCurrentLabel") }, rootClass: {}, mobileClass: {}, mobileSortClass: {}, wrapperClass: {}, stickyHeaderClass: {}, scrollableClass: {}, tableClass: {}, borderedClass: {}, stripedClass: {}, narrowedClass: {}, hoverableClass: {}, emptyClass: {}, thClass: {}, thPositionClass: {}, thCheckboxClass: {}, thStickyClass: {}, thDetailedClass: {}, thSortableClass: {}, thSortIconClass: {}, thCurrentSortClass: {}, thUnselectableClass: {}, thSubheadingClass: {}, trSelectedClass: {}, trCheckedClass: {}, trDetailedClass: {}, trEmptyClass: {}, tdClass: {}, tdPositionClass: {}, tdStickyClass: {}, tdCheckboxClass: {}, tdDetailedChevronClass: {}, paginationWrapperClass: {}, footerClass: {}, loadingClasses: {} }, { "currentPage": { default: 1 }, "currentPageModifiers": {}, "selected": { default: void 0 }, "selectedModifiers": {}, "checkedRows": { default: [] }, "checkedRowsModifiers": {}, "detailedRows": { default: [] }, "detailedRowsModifiers": {} }), emits: /* @__PURE__ */ vue.mergeModels(["update:currentPage", "page-change", "update:selected", "select", "check", "check-all", "update:checkedRows", "sort", "filters-change", "filters-event", "update:detailedRows", "details-open", "details-close", "click", "dblclick", "contextmenu", "mouseenter", "mouseleave", "cell-click", "dragstart", "dragend", "drop", "dragleave", "dragover", "columndragstart", "columndragend", "columndrop", "columndragleave", "columndragover"], ["update:currentPage", "update:selected", "update:checkedRows", "update:detailedRows"]), setup(__props, { expose: __expose, emit: __emit }) { const props = __props; const emits = __emit; const slots = vue.useSlots(); const { isMobile } = useMatchMedia.useMatchMedia(props.mobileBreakpoint); const isMobileActive = vue.computed(() => props.mobileCards && isMobile.value); const slotsRef = vue.useTemplateRef("slotsWrapper"); const provideData = vue.computed(() => ({ isColumnSorted })); const { childItems } = useParentProvider.useProviderParent({ rootRef: slotsRef, data: provideData }); const tableColumns = vue.computed(() => { if (!childItems.value.length) return []; return childItems.value.map((columnItem) => { const column = vue.toValue(columnItem.data); let thAttrsData = typeof props.thAttrs === "function" ? props.thAttrs(column) : {}; thAttrsData = Object.assign(thAttrsData, column.thAttrs); const tdAttrsData = (props.data ?? []).map((data) => { const tdAttrs = typeof props.tdAttrs === "function" ? props.tdAttrs(data, column) : {}; return Object.assign(tdAttrs, column.tdAttrs); }); return { ...column, value: column, index: columnItem.index, identifier: columnItem.identifier, thAttrsData, tdAttrsData }; }); }); const columnCount = vue.computed(() => { let i = tableColumns.value.length; if (showDetailRowIcon.value) i++; if (props.checkable) i++; return i; }); const ariaColIndexStart = vue.computed(() => { let i = 1; if (showDetailRowIcon.value) i++; if (props.checkable && props.checkboxPosition === "left") i++; return i; }); const hasSubheadings = vue.computed(() => { if (slots.subheading) return true; return tableColumns.value.some((column) => !!column.subheading); }); const isScrollable = vue.computed(() => { if (props.scrollable) return true; return tableColumns.value.some((column) => column.sticky); }); const tableCurrentPage = vue.useModel(__props, "currentPage"); vue.watch( [ tableCurrentPage, () => props.perPage, () => props.data, () => props.paginated ], () => filterTableRows() ); const { nextSequence } = useSequentialId.useSequentialId(); const tableRows = vue.computed(() => { if (!props.data) return []; return props.data.map((value, idx) => ({ label: "row " + idx, // row display label value: vue.toValue(value), // normalizes wrapped ref values index: idx, // row index key: ( // if no key is given and data is object, create unique row id for each row String(helpers.getValueByPath(value, props.rowKey) || nextSequence()) ) })); }); const availableRows = vue.computed( () => tableRows.value.filter(useOptions.isOptionViable) ); function filterTableRows() { const currentPage = tableCurrentPage.value; const perPage = Number(props.perPage); const pageStart = (currentPage - 1) * perPage; const pageEnd = pageStart + perPage; useOptions.filterOptionsItems(tableRows, (row, idx) => { if (props.paginated && !props.backendPagination) { if (tableRows.value.length > perPage && (idx < pageStart || idx >= pageEnd)) return true; } if (!props.backendFiltering) return !isRowFiltered(row.value); return false; }); } const tableTotal = vue.computed( () => props.backendPagination ? props.total : tableRows.value.length ); const rowCount = vue.computed(() => { return tableTotal.value + ariaRowIndexStart.value; }); const ariaRowIndexStart = vue.computed(() => { let i = 1; if (hasSearchableColumns.value) i++; if (hasSubheadings.value) i++; return i; }); function hasCustomFooterSlot() { if (!slots.footer) return false; const footer = slots.footer({ columnCount: columnCount.value, rowCount: rowCount.value }); if (footer.length > 1) return true; const tag = footer[0]["type"]; return tag === "th" || tag === "td"; } function getColumnValue(row, column) { return helpers.getPropertyValue(row, column.field, column.formatter); } function isRowEqual(sourceRow, targetRow) { const el1 = vue.toRaw(vue.toValue(sourceRow)); const el2 = vue.toRaw(vue.toValue(targetRow)); if (!helpers.isDefined(targetRow)) return false; if (typeof props.customCompare === "function") return props.customCompare(el1, el2); if (props.rowKey) return helpers.getPropertyValue(el1, props.rowKey) == helpers.getPropertyValue(el2, props.rowKey); return el1 == el2; } const tableSelectedRow = vue.useModel(__props, "selected"); function onArrowPressed(delta, event) { if (!availableRows.value.length) return; let index2 = availableRows.value.findIndex( (row2) => isRowEqual(row2.value, tableSelectedRow.value) ) + delta; index2 = index2 > availableRows.value.length - 1 ? availableRows.value.length - 1 : index2; index2 = index2 < 0 ? 0 : index2; const row = availableRows.value[index2]; if (!props.isRowSelectable(row.value)) { let newIndex; if (delta > 0) { for (let i = index2; i < availableRows.value.length && newIndex === void 0; i++) { if (props.isRowSelectable(availableRows.value[i].value)) newIndex = i; } } else { for (let i = index2; i >= 0 && newIndex === void 0; i--) { if (props.isRowSelectable(availableRows.value[i].value)) newIndex = i; } } if (newIndex != void 0 && newIndex >= 0) selectRow(availableRows.value[newIndex], event); } else { selectRow(row, event); } } function selectRow(row, event) { emits("click", row.value, row.index, event); if (!props.selectable) return; if (isRowEqual(tableSelectedRow, row.value)) return; if (!props.isRowSelectable(row.value)) return; tableSelectedRow.value = row.value; emits("select", row.value, tableSelectedRow.value); } const filters = vue.ref({}); const hasSearchableColumns = vue.computed( () => tableColumns.value.some((column) => column.searchable) ); let debouncedFilter; vue.watch( () => props.filterDebounce, (debounce) => debouncedFilter = useDebounce.useDebounce(handleFiltersChange, debounce || 0), { immediate: true } ); vue.watch(filters, (value) => debouncedFilter(value), { deep: true }); function handleFiltersChange(value) { emits("filters-change", value); if (!props.backendFiltering) { filterTableRows(); vue.triggerRef(tableRows); } } function onFiltersEvent(event) { emits("filters-event", props.filtersEvent, filters.value, event); } function isRowFiltered(row) { if (!Object.values(filters.value).filter(Boolean).length) return true; return Object.entries(filters.value).some(([key, filter]) => { if (!filter) return false; const column = tableColumns.value.find((c) => c.field === key); if (typeof (column == null ? void 0 : column.customSearch) === "function") return column.customSearch(row, filter); const value = typeof row === "object" && !!row ? helpers.getValueByPath(row, key) : row; if (value == null) return false; if (Number.isInteger(value)) return value === Number(filter); const re = new RegExp(helpers.escapeRegExpChars(filter), "i"); if (Array.isArray(value)) return value.some( (val) => re.test(helpers.removeDiacriticsFromString(val)) || re.test(val) ); if (typeof value !== "string") return !!value; return re.test(helpers.removeDiacriticsFromString(value)) || re.test(value); }); } const currentSortColumn = vue.ref(); const isAsc = vue.ref(true); const hasSortableColumns = vue.computed( () => tableColumns.value.some((column) => column.sortable) ); function isColumnSorted(column) { var _a; return ((_a = currentSortColumn.value) == null ? void 0 : _a.identifier) === column.identifier; } vue.onMounted(() => vue.nextTick(() => initSort())); function initSort() { if (!tableColumns.value.length || currentSortColumn.value) return; if (!props.defaultSort) return; let sortField = ""; let sortDirection = props.defaultSortDirection; if (Array.isArray(props.defaultSort)) { sortField = props.defaultSort[0]; if (props.defaultSort[1]) sortDirection = props.defaultSort[1]; } else { sortField = props.defaultSort; } sortByField(sortField, sortDirection); } function sortByField(field, direction) { const sortColumn = tableColumns.value.find( (column) => column.field === field ); if (sortColumn) { isAsc.value = direction.toLowerCase() === "asc"; sort(sortColumn); } } function sort(column, updateDirection = false, event) { if (!(column == null ? void 0 : column.sortable)) return; if (updateDirection) isAsc.value = isColumnSorted(column) ? !isAsc.value : props.defaultSortDirection.toLowerCase() === "asc"; if (currentSortColumn.value) emits( "sort", column, isAsc.value ? "asc" : "desc", event || new Event("sort") ); currentSortColumn.value = column; if (!props.backendSorting) { sortByColumn(tableRows.value); filterTableRows(); } } function sortByColumn(rows) { const column = currentSortColumn.value; if (!column) return rows; return helpers.sortBy( rows, (column == null ? void 0 : column.field) ? "value." + column.field : "", (column == null ? void 0 : column.customSort) ? (a, b, asc) => column.customSort(a.value, b.value, asc) : void 0, isAsc.value, true ); } const tableCheckedRows = vue.useModel(__props, "checkedRows"); const isAllChecked = vue.computed(() => { const validVisibleData = availableRows.value.filter( (row) => props.isRowCheckable(row.value) ); if (validVisibleData.length === 0) return false; return validVisibleData.every( (currentVisibleRow) => isChecked(currentVisibleRow) ); }); const isAllUncheckable = vue.computed( () => !availableRows.value.some((row) => props.isRowCheckable(row.value)) ); function isChecked(row) { if (typeof props.isRowChecked === "function") return props.isRowChecked(row.value); else return tableCheckedRows.value.some((r) => isRowEqual(r, row.value)); } function addCheckedRow(row) { tableCheckedRows.value = [...tableCheckedRows.value, row.value]; } function removeCheckedRow(row) { const idx = tableCheckedRows.value.findIndex( (r) => isRowEqual(r, row.value) ); if (idx >= 0) tableCheckedRows.value = tableCheckedRows.value.toSpliced(idx, 1); } function checkAll() { if (isAllChecked.value) tableCheckedRows.value = []; else { tableCheckedRows.value = availableRows.value.filter((row) => props.isRowCheckable(row.value)).map((row) => row.value); } vue.nextTick(() => emits("check-all", tableCheckedRows.value)); } function checkRow(row) { if (!props.isRowCheckable(row.value)) return; if (isChecked(row)) removeCheckedRow(row); else addCheckedRow(row); vue.nextTick(() => emits("check", tableCheckedRows.value, row.value)); } const visibleDetailedRows = vue.useModel(__props, "detailedRows"); const showDetailRowIcon = vue.computed( () => props.detailed && props.showDetailIcon ); function toggleDetails(row) { if (isDetailRowVisible(row)) { closeDetailRow(row); emits("details-close", row.value); } else { openDetailRow(row); emits("details-open", row.value); } } function openDetailRow(row) { visibleDetailedRows.value = [...visibleDetailedRows.value, row.value]; } function closeDetailRow(row) { const idx = visibleDetailedRows.value.findIndex( (r) => isRowEqual(r, row.value) ); if (idx >= 0) visibleDetailedRows.value = visibleDetailedRows.value.toSpliced(idx, 1); } function isDetailRowVisible(row) { return props.detailed && visibleDetailedRows.value.some((r) => isRowEqual(r, row.value)); } const isDraggingRow = vue.ref(false); const isDraggingColumn = vue.ref(false); const canDragRow = vue.computed(() => props.draggable && !isDraggingColumn.value); const canDragColumn = vue.computed( () => props.draggableColumn && !isDraggingRow.value ); function handleDragStart(row, event) { if (!props.draggable) return; emits("dragstart", row.value, row.index, event); } function handleDragEnd(row, event) { if (!props.draggable) return; emits("dragend", row.value, row.index, event); } function handleDrop(row, event) { if (!props.draggable) return; emits("drop", row.value, row.index, event); } function handleDragOver(row, event) { if (!props.draggable) return; emits("dragover", row.value, row.index, event); } function handleDragLeave(row, event) { if (!props.draggable) return; emits("dragleave", row.value, row.index, event); } function handleColumnDragStart(column, event) { if (!canDragColumn.value) return; isDraggingColumn.value = true; emits("columndragstart", column.value, column.index, event); } function handleColumnDragEnd(column, event) { if (!canDragColumn.value) return; isDraggingColumn.value = false; emits("columndragend", column.value, column.index, event); } function handleColumnDrop(column, event) { if (!canDragColumn.value) return; emits("columndrop", column.value, column.index, event); } function handleColumnDragOver(column, event) { if (!canDragColumn.value) return; emits("columndragover", column.value, column.index, event); } function handleColumnDragLeave(column, event) { if (!canDragColumn.value) return; emits("columndragleave", column.value, column.index, event); } const rootClasses = defineClasses.defineClasses( ["rootClass", "o-table__root"], ["mobileClass", "o-table__root--mobile", null, isMobileActive] ); const tableWrapperClasses = defineClasses.defineClasses( ["wrapperClass", "o-table__wrapper"], [ "stickyHeaderClass", "o-table__wrapper--sticky-header", null, vue.computed(() => props.stickyHeader) ], ["scrollableClass", "o-table__wrapper--scrollable", null, isScrollable], ["mobileClass", "o-table__wrapper--mobile", null, isMobileActive] ); const tableWrapperStyle = vue.computed(() => ({ height: helpers.toCssDimension(props.height) })); const tableClasses = defineClasses.defineClasses( ["tableClass", "o-table"], [ "borderedClass", "o-table--bordered", null, vue.computed(() => props.bordered) ], ["stripedClass", "o-table--striped", null, vue.computed(() => props.striped)], [ "narrowedClass", "o-table--narrowed", null, vue.computed(() => props.narrowed) ], [ "hoverableClass", "o-table--hoverable", null, vue.computed( () => (props.hoverable || props.selectable) && !!availableRows.value.length ) ], [ "emptyClass", "o-table--empty", null, vue.computed(() => !availableRows.value.length) ] ); const thBaseClasses = defineClasses.defineClasses(["thClass", "o-table__th"]); const thCheckboxClasses = defineClasses.defineClasses( ["thCheckboxClass", "o-table__th-checkbox"], [ "thStickyClass", "o-table__th--sticky", null, vue.computed(() => props.stickyCheckbox) ] ); const thDetailedClasses = defineClasses.defineClasses([ "thDetailedClass", "o-table__th-detailed" ]); const thSubheadingClasses = defineClasses.defineClasses([ "thSubheadingClass", "o-table__th-subheading" ]); const thSortIconClasses = defineClasses.defineClasses([ "thSortIconClass", "o-table__th__sort-icon" ]); const trSelectedClasses = defineClasses.defineClasses([ "trSelectedClass", "o-table__tr--selected" ]); const trCheckedClasses = defineClasses.defineClasses([ "trCheckedClass", "o-table__tr--checked" ]); const trEmptyClasses = defineClasses.defineClasses(["trEmptyClass", "o-table__tr-empty"]); const trDetailedClasses = defineClasses.defineClasses([ "trDetailedClass", "o-table__tr-detail" ]); const tdBaseClasses = defineClasses.defineClasses(["tdClass", "o-table__td"]); const tdCheckboxClasses = defineClasses.defineClasses( ["tdCheckboxClass", "o-table__td-checkbox"], [ "thStickyClass", "o-table__th--sticky", null, vue.computed(() => props.stickyCheckbox) ] ); const tdDetailedChevronClasses = defineClasses.defineClasses([ "tdDetailedChevronClass", "o-table__td-chevron" ]); const footerClasses = defineClasses.defineClasses(["footerClass", "o-table__footer"]); const mobileSortClasses = defineClasses.defineClasses([ "mobileSortClass", "o-table__mobile-sort" ]); const paginationWrapperClasses = defineClasses.defineClasses([ "paginationWrapperClass", "o-table__pagination" ]); const paginationWrapperRootClasses = vue.computed( () => defineClasses.getActiveClasses(paginationWrapperClasses) ); function rowClasses(row) { const selectedClasses = isRowEqual(row.value, tableSelectedRow.value) ? trSelectedClasses.value : []; const checkedClasses = isChecked(row) ? trCheckedClasses.value : []; const rowClass = typeof props.rowClass === "function" ? props.rowClass(row.value, row.index) || "" : ""; return [...selectedClasses, ...checkedClasses, { [rowClass]: true }]; } filterTableRows(); __expose({ rows: tableRows, sort: sortByField }); return (_ctx, _cache) => { return vue.openBlock(), vue.createElementBlock("div", { "data-oruga": "table", class: vue.normalizeClass(vue.unref(rootClasses)) }, [ vue.createElementVNode("div", _hoisted_1, [ vue.renderSlot(_ctx.$slots, "default", {}, () => { var _a; return [ vue.renderSlot(_ctx.$slots, "before"), ((_a = _ctx.columns) == null ? void 0 : _a.length) ? (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 0 }, vue.renderList(_ctx.columns, (column, idx) => { return vue.openBlock(), vue.createBlock(_sfc_main$2, vue.mergeProps({ key: column.field || idx, ref_for: true }, column), { default: vue.withCtx(({ row }) => [ vue.createTextVNode(vue.toDisplayString(getColumnValue(row, column)), 1) ]), _: 2 }, 1040); }), 128)) : vue.createCommentVNode("", true), vue.renderSlot(_ctx.$slots, "after") ]; }) ], 512), isMobileActive.value && hasSortableColumns.value ? (vue.openBlock(), vue.createBlock(_sfc_main$3, { key: 0, "current-sort-column": currentSortColumn.value, columns: tableColumns.value, placeholder: _ctx.mobileSortPlaceholder, "icon-pack": _ctx.iconPack, "sort-icon": _ctx.sortIcon, "sort-icon-size": _ctx.sortIconSize, "is-asc": isAsc.value, "mobile-sort-classes": vue.unref(mobileSortClasses), onSort: _cache[0] || (_cache[0] = (column, event) => sort(column, true, event)) }, null, 8, ["current-sort-column", "columns", "placeholder", "icon-pack", "sort-icon", "sort-icon-size", "is-asc", "mobile-sort-classes"])) : vue.createCommentVNode("", true), _ctx.paginated && (_ctx.paginationPosition === "top" || _ctx.paginationPosition === "both") ? vue.renderSlot(_ctx.$slots, "pagination", { key: 1, current: tableCurrentPage.value, perPage: _ctx.perPage, total: tableTotal.value, change: (page) => tableCurrentPage.value = page }, () => [ vue.createVNode(_sfc_main$1, { current: tableCurrentPage.value, "onUpdate:current": _cache[1] || (_cache[1] = ($event) => tableCurrentPage.value = $event), paginated: _ctx.paginated, "per-page": _ctx.perPage, total: tableTotal.value, rounded: _ctx.paginationRounded, size: _ctx.paginationSize, order: _ctx.paginationOrder, simple: _ctx.paginationSimple, "range-before": _ctx.paginationRangeBefore, "range-after": _ctx.paginationRangeAfter, "icon-pack": _ctx.iconPack, "aria-next-label": _ctx.ariaNextLabel, "aria-previous-label": _ctx.ariaPreviousLabel, "aria-page-label": _ctx.ariaPageLabel, "aria-current-label": _ctx.ariaCurrentLabel, "root-class": paginationWrapperRootClasses.value, onChange: _cache[2] || (_cache[2] = (page) => _ctx.$emit("page-change", page)) }, { default: vue.withCtx(() => [ vue.renderSlot(_ctx.$slots, "top-left") ]), _: 3 }, 8, ["current", "paginated", "per-page", "total", "rounded", "size", "order", "simple", "range-before", "range-after", "icon-pack", "aria-next-label", "aria-previous-label", "aria-page-label", "aria-current-label", "root-class"]) ]) : vue.createCommentVNode("", true), vue.createElementVNode("div", { class: vue.normalizeClass(vue.unref(tableWrapperClasses)), style: vue.normalizeStyle(tableWrapperStyle.value) }, [ tableColumns.value.length ? (vue.openBlock(), vue.createElementBlock("table", vue.mergeProps({ key: 0 }, _ctx.$attrs, { class: vue.unref(tableClasses), tabindex: _ctx.selectable || isScrollable.value ? 0 : void 0, "aria-rowcount": rowCount.value, "aria-colcount": columnCount.value, onKeydown: [ _cache[3] || (_cache[3] = vue.withKeys(vue.withModifiers(($event) => onArrowPressed(-1, $event), ["prevent"]), ["up"])), _cache[4] || (_cache[4] = vue.withKeys(vue.withModifiers(($event) => onArrowPressed(1, $event), ["prevent"]), ["down"])), _cache[5] || (_cache[5] = vue.withKeys(vue.withModifiers(($event) => selectRow(availableRows.value[0], $event), ["prevent"]), ["home"])), _cache[6] || (_cache[6] = vue.withKeys(vue.withModifiers(($event) => selectRow(availableRows.value[availableRows.value.length - 1], $event), ["prevent"]), ["end"])) ] }), [ _ctx.$slots.caption ? (vue.openBlock(), vue.createElementBlock("caption", _hoisted_3, [ vue.renderSlot(_ctx.$slots, "caption") ])) : vue.createCommentVNode("", true), _ctx.showHeader ? (vue.openBlock(), vue.createElementBlock("thead", _hoisted_4, [ vue.renderSlot(_ctx.$slots, "preheader"), vue.createElementVNode("tr", _hoisted_5, [ showDetailRowIcon.value ? (vue.openBlock(), vue.createElementBlock("th", { key: 0, class: vue.normalizeClass([...vue.unref(thBaseClasses), ...vue.unref(thDetailedClasses)]), "aria-colindex": 1, "aria-hidden": "true" }, null, 2)) : vue.createCommentVNode("", true), _ctx.checkable && _ctx.checkboxPosition === "left" ? (vue.openBlock(), vue.createElementBlock("th", { key: 1, class: vue.normalizeClass([...vue.unref(thBaseClasses), ...vue.unref(thCheckboxClasses)]), "aria-colindex": showDetailRowIcon.value ? 2 : 1 }, [ _ctx.checkableHeader ? vue.renderSlot(_ctx.$slots, "check-all", { key: 0, isAllChecked: isAllChecked.value, isAllUncheckable: isAllUncheckable.value, checkAll }, () => [ vue.createVNode(Checkbox_vue_vue_type_script_setup_true_lang._sfc_main, { "model-value": isAllChecked.value, autocomplete: "off", name: "row_check_all", variant: _ctx.checkboxVariant, disabled: isAllUncheckable.value, "aria-label": "Check all", "onUpdate:modelValue": checkAll }, null, 8, ["model-value", "variant", "disabled"]) ]) : vue.createCommentVNode("", true) ], 10, _hoisted_6)) : vue.createCommentVNode("", true), (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(tableColumns.value, (column) => { var _a; return vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: column.identifier }, [ !column.hidden ? (vue.openBlock(), vue.createElementBlock("th", vue.mergeProps({ key: 0, ref_for: true }, column.thAttrsData, { class: [...vue.unref(thBaseClasses), ...column.thClasses], style: isMobileActive.value ? {} : column.style, draggable: canDragColumn.value, "aria-sort": isColumnSorted(column) ? isAsc.value ? "ascending" : "descending" : void 0, "aria-colindex": ariaColIndexStart.value + column.index, onClick: vue.withModifiers(($event) => sort(column, true, $event), ["stop"]), onDragstart: ($event) => handleColumnDragStart(column, $event), onDragend: ($event) => handleColumnDragEnd(column, $event), onDrop: ($event) => handleColumnDrop(column, $event), onDragover: ($event) => handleColumnDragOver(column, $event), onDragleave: ($event) => handleColumnDragLeave(column, $event) }), [ ((_a = column.$slots) == null ? void 0 : _a.header) ? (vue.openBlock(), vue.createBlock(vue.unref(SlotComponent.OSlotComponent), { key: 0, component: column.$el, name: "header", tag: "span", props: { column: column.value, index: column.index } }, null, 8, ["component", "props"])) : (vue.openBlock(), vue.createElementBlock("span", _hoisted_8, [ vue.createTextVNode(vue.toDisplayString(column.label) + " ", 1), column.sortable ? vue.withDirectives((vue.openBlock(), vue.createElementBlock("span", { key: 0, class: vue.normalizeClass(vue.unref(thSortIconClasses)), "aria-hidden": !isColumnSorted(column) }, [ vue.createVNode(Icon_vue_vue_type_script_setup_true_lang._sfc_main, { icon: _ctx.sortIcon, pack: _ctx.iconPack, size: _ctx.sortIconSize, rotation: !isAsc.value ? 180 : 0 }, null, 8, ["icon", "pack", "size", "rotation"]) ], 10, _hoisted_9)), [ [vue.vShow, isColumnSorted(column)] ]) : vue.createCommentVNode("", true) ])) ], 16, _hoisted_7)) : vue.createCommentVNode("", true) ], 64); }), 128)), _ctx.checkable && _ctx.checkboxPosition === "right" ? (vue.openBlock(), vue.createElementBlock("th", { key: 2, class: vue.normalizeClass([...vue.unref(thBaseClasses), ...vue.unref(thCheckboxClasses)]), "aria-colindex": ariaColIndexStart.value + tableColumns.value.length }, [ _ctx.checkableHeader ? vue.renderSlot(_ctx.$slots, "check-all", { key: 0, isAllChecked: isAllChecked.value, isAllUncheckable: isAllUncheckable.value, checkAll }, () => [ vue.createVNode(Checkbox_vue_vue_type_script_setup_true_lang._sfc_main, { "model-value": isAllChecked.value, autocomplete: "off", name: "row_check_all", variant: _ctx.checkboxVariant, disabled: isAllUncheckable.value, "aria-label": "Check all", "onUpdate:modelValue": checkAll }, null, 8, ["model-value", "variant", "disabled"]) ]) : vue.createCommentVNode("", true) ], 10, _hoisted_10)) : vue.createCommentVNode("", true) ]), hasSearchableColumns.value ? (vue.openBlock(), vue.createElementBlock("tr", _hoisted_11, [ showDetailRowIcon.value ? (vue.openBlock(), vue.createElementBlock("th", { key: 0, class: vue.normalizeClass([...vue.unref(thBaseClasses), ...vue.unref(thDetailedClasses)]), "aria-hidden": "true" }, null, 2)) : vue.createCommentVNode("", true), _ctx.checkable && _ctx.checkboxPosition === "left" ? (vue.openBlock(), vue.createElementBlock("th", _hoisted_12)) : vue.createCommentVNode("", true), (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(tableColumns.value, (column) => { var _a; return vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: column.identifier }, [ !column.hidden ? (vue.openBlock(), vue.createElementBlock("th", vue.mergeProps({ key: 0,