UNPKG

bootstrap-vue-next

Version:

Seamless integration of Vue 3, Bootstrap 5, and TypeScript for modern, type-safe UI development

1,264 lines 68.3 kB
require("./chunk-CoQrYLCe.js"); const require_keys = require("./keys-durSVUrO.js"); const require_dist = require("./dist-B_c893QG.js"); const require_dom = require("./dom-Bs6DzM72.js"); const require_useId = require("./useId-DTrBK9CE.js"); const require_useDefaults = require("./useDefaults-DK6Y9lar.js"); const require_object = require("./object-CPeShLVx.js"); require("./constants-DMR5FAE3.js"); const require_stringUtils = require("./stringUtils-hUreqC0N.js"); require("./src/types/index.umd.js"); const require_debounce = require("./debounce-BfDJWP7y.js"); const require_BTableSimple = require("./BTableSimple-fwaF0Kws.js"); let vue = require("vue"); //#region src/types/TableTypes.ts var isTableItem = (value) => typeof value === "object" && value !== null; var isTableField = (value) => typeof value === "object" && value !== null && "key" in value; //#endregion //#region src/components/BTable/BTbody.vue var BTbody_default = /* @__PURE__ */ (0, vue.defineComponent)({ __name: "BTbody", props: { variant: { default: null } }, setup(__props) { const props = require_useDefaults.useDefaults(__props, "BTbody"); const computedClasses = (0, vue.computed)(() => ({ [`thead-${props.variant}`]: props.variant !== null })); return (_ctx, _cache) => { return (0, vue.openBlock)(), (0, vue.createElementBlock)("tbody", { class: (0, vue.normalizeClass)(computedClasses.value) }, [(0, vue.renderSlot)(_ctx.$slots, "default")], 2); }; } }); //#endregion //#region src/components/BTable/BTd.vue?vue&type=script&setup=true&lang.ts var _hoisted_1$3 = [ "colspan", "rowspan", "data-label" ]; var _hoisted_2$3 = { key: 0 }; //#endregion //#region src/components/BTable/BTd.vue var BTd_default = /* @__PURE__ */ (0, vue.defineComponent)({ __name: "BTd", props: { colspan: { default: void 0 }, rowspan: { default: void 0 }, stackedHeading: { default: void 0 }, stickyColumn: { type: Boolean, default: false }, variant: { default: null } }, setup(__props) { const props = require_useDefaults.useDefaults(__props, "BTd"); const computedClasses = (0, vue.computed)(() => ({ [`table-${props.variant}`]: props.variant !== null, "b-table-sticky-column": props.stickyColumn, "table-b-table-default": props.stickyColumn && props.variant === null })); return (_ctx, _cache) => { return (0, vue.openBlock)(), (0, vue.createElementBlock)("td", { class: (0, vue.normalizeClass)(computedClasses.value), colspan: (0, vue.unref)(props).colspan, rowspan: (0, vue.unref)(props).rowspan, "data-label": (0, vue.unref)(props).stackedHeading }, [(0, vue.unref)(props).stackedHeading ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_2$3, [(0, vue.renderSlot)(_ctx.$slots, "default")])) : (0, vue.renderSlot)(_ctx.$slots, "default", { key: 1 })], 10, _hoisted_1$3); }; } }); //#endregion //#region src/components/BTable/BTfoot.vue var BTfoot_default = /* @__PURE__ */ (0, vue.defineComponent)({ __name: "BTfoot", props: { variant: { default: null } }, setup(__props) { const props = require_useDefaults.useDefaults(__props, "BTfoot"); const computedClasses = (0, vue.computed)(() => ({ [`table-${props.variant}`]: props.variant !== null })); return (_ctx, _cache) => { return (0, vue.openBlock)(), (0, vue.createElementBlock)("tfoot", { class: (0, vue.normalizeClass)(computedClasses.value) }, [(0, vue.renderSlot)(_ctx.$slots, "default")], 2); }; } }); //#endregion //#region src/components/BTable/BTh.vue?vue&type=script&setup=true&lang.ts var _hoisted_1$2 = [ "scope", "colspan", "rowspan", "data-label" ]; var _hoisted_2$2 = { key: 0 }; //#endregion //#region src/components/BTable/BTh.vue var BTh_default = /* @__PURE__ */ (0, vue.defineComponent)({ __name: "BTh", props: { colspan: { default: void 0 }, rowspan: { default: void 0 }, stackedHeading: { default: void 0 }, stickyColumn: { type: Boolean, default: false }, variant: { default: null }, scope: { default: void 0 } }, setup(__props) { const props = require_useDefaults.useDefaults(__props, "BTh"); const computedClasses = (0, vue.computed)(() => ({ [`table-${props.variant}`]: props.variant !== null, "b-table-sticky-column": props.stickyColumn, "table-b-table-default": props.stickyColumn && props.variant === null })); const localScope = (0, vue.computed)(() => props.scope ? props.scope : props.colspan ? "colgroup" : props.rowspan ? "rowgroup" : "col"); return (_ctx, _cache) => { return (0, vue.openBlock)(), (0, vue.createElementBlock)("th", { scope: localScope.value, class: (0, vue.normalizeClass)(computedClasses.value), colspan: (0, vue.unref)(props).colspan, rowspan: (0, vue.unref)(props).rowspan, "data-label": (0, vue.unref)(props).stackedHeading }, [(0, vue.unref)(props).stackedHeading !== void 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_2$2, [(0, vue.renderSlot)(_ctx.$slots, "default")])) : (0, vue.renderSlot)(_ctx.$slots, "default", { key: 1 })], 10, _hoisted_1$2); }; } }); //#endregion //#region src/components/BTable/BThead.vue var BThead_default = /* @__PURE__ */ (0, vue.defineComponent)({ __name: "BThead", props: { variant: { default: null } }, setup(__props) { const props = require_useDefaults.useDefaults(__props, "BThead"); const computedClasses = (0, vue.computed)(() => ({ [`table-${props.variant}`]: props.variant !== null })); return (_ctx, _cache) => { return (0, vue.openBlock)(), (0, vue.createElementBlock)("thead", { class: (0, vue.normalizeClass)(computedClasses.value) }, [(0, vue.renderSlot)(_ctx.$slots, "default")], 2); }; } }); //#endregion //#region src/components/BTable/BTr.vue var BTr_default = /* @__PURE__ */ (0, vue.defineComponent)({ __name: "BTr", props: { variant: { default: null } }, setup(__props) { const props = require_useDefaults.useDefaults(__props, "BTr"); const computedClasses = (0, vue.computed)(() => ({ [`table-${props.variant}`]: props.variant !== null })); return (_ctx, _cache) => { return (0, vue.openBlock)(), (0, vue.createElementBlock)("tr", { class: (0, vue.normalizeClass)(computedClasses.value) }, [(0, vue.renderSlot)(_ctx.$slots, "default")], 2); }; } }); //#endregion //#region src/utils/tableUtils.ts var getTableFieldHeadLabel = (field) => typeof field === "string" ? require_stringUtils.titleCase(field) : field.label !== void 0 ? field.label : require_stringUtils.titleCase(field.key); var getWithGetter = (item, key) => { if (typeof key === "function") return key(item); return item[key]; }; var getByFieldKey = (item, field) => typeof item === "object" && item !== null ? getWithGetter(item, field.accessor ?? field.key) : item; var formatItem = (item, field) => { const val = getByFieldKey(item, field); return typeof field.formatter === "function" ? field.formatter({ value: val, key: field.key, item }) : val; }; var bTableSimpleProps = Object.freeze(Object.keys({ bordered: 0, borderless: 0, borderVariant: 0, captionTop: 0, dark: 0, fixed: 0, hover: 0, id: 0, noBorderCollapse: 0, outlined: 0, responsive: 0, small: 0, stacked: 0, stickyHeader: 0, striped: 0, stripedColumns: 0, variant: 0, tableAttrs: 0, tableClass: 0 })); var bTableLiteProps = Object.freeze(Object.keys({ align: 0, caption: 0, detailsTdClass: 0, fieldColumnClass: 0, fields: 0, footClone: 0, footRowVariant: 0, footVariant: 0, headRowVariant: 0, headVariant: 0, items: 0, labelStacked: 0, modelValue: 0, primaryKey: 0, tbodyClass: 0, tbodyTrAttrs: 0, tbodyTrClass: 0, tfootClass: 0, expandedItems: 0, tfootTrClass: 0, theadClass: 0, theadTrClass: 0 })); var getDataLabelAttr = (props, label) => props.stacked && props.labelStacked !== true ? { "data-label": label } : void 0; //#endregion //#region src/utils/filterEvent.ts var TABLE_TAG_NAMES = [ "TD", "TH", "TR" ]; var eventFilter = [ "a", "a *", "button", "button *", "input:not(.disabled):not([disabled])", "select:not(.disabled):not([disabled])", "textarea:not(.disabled):not([disabled])", "[role=\"link\"]", "[role=\"link\"] *", "[role=\"button\"]", "[role=\"button\"] *", "[tabindex]:not(.disabled):not([disabled])" ].join(","); var filterEvent = (event) => { if (!event || !event.target) return false; const el = event.target; if ("disabled" in el && el.disabled || TABLE_TAG_NAMES.indexOf(el.tagName) !== -1) return false; if (el.closest(".dropdown-menu")) return true; const label = el.tagName === "LABEL" ? el : el.closest("label"); if (label) { const doc = require_dom.getSafeDocument(); const labelFor = label.getAttribute("for"); const input = labelFor ? doc?.getElementById(labelFor) : label.querySelector("input, select, textarea"); if (input && !input.disabled) return true; } return el.matches(eventFilter); }; //#endregion //#region src/composables/useTableLiteHelpers.ts var useTableFieldsMapper = ({ fields, items, stackedProps }) => { const computedFields = (0, vue.computed)(() => { const fieldsValue = (0, vue.toValue)(fields); const itemsValue = (0, vue.toValue)(items); const stacked = { stacked: (0, vue.toValue)(stackedProps.stacked), labelStacked: (0, vue.toValue)(stackedProps.labelStacked) }; if (!fieldsValue.length && itemsValue.length) { const [firstItem] = itemsValue; if (firstItem && (isTableItem(firstItem) || Array.isArray(firstItem))) return { items: Object.keys(firstItem).map((k) => { const label = require_stringUtils.startCase(k); return { key: k, label, tdAttr: getDataLabelAttr(stacked, label) }; }) }; return { items: [{ key: "" }], opts: { noHeader: true } }; } return { items: fieldsValue.map((f) => { if (isTableField(f)) { const dataLabelAttr = getDataLabelAttr(stacked, f.label ?? require_stringUtils.startCase(f.key)); const tdAttr = typeof f.tdAttr === "function" ? (obj) => ({ ...dataLabelAttr, ...f.tdAttr(obj) }) : dataLabelAttr || f.tdAttr ? { ...dataLabelAttr, ...f.tdAttr } : void 0; return { ...f, tdAttr }; } const label = require_stringUtils.startCase(f); return { key: f, label, tdAttr: getDataLabelAttr(stacked, label) }; }) }; }); const total = (0, vue.computed)(() => computedFields.value.items.length); return { total, showHeaders: (0, vue.computed)(() => !(total.value > 0 && computedFields.value.opts?.noHeader === true)), fields: (0, vue.computed)(() => computedFields.value.items) }; }; var useItemTracker = ({ allItems, selectedItems, primaryKey }) => { const isActivated = (0, vue.computed)(() => selectedItems.value.length > 0); const pKey = (0, vue.readonly)((0, vue.toRef)(primaryKey)); const get = (item) => { if (typeof item === "object" && item !== null && pKey.value) return getWithGetter(item, pKey.value); return item; }; const add = (item) => { const value = get(item); selectedItems.value = [...selectedItems.value, value]; }; const set = (items) => { selectedItems.value = pKey.value ? items.map(get) : items; }; const setAll = () => set([...(0, vue.toValue)(allItems)]); const remove = (item) => { const value = get(item); selectedItems.value = selectedItems.value.filter((i) => i !== value); }; const clear = () => { selectedItems.value = []; }; const has = (item) => { const value = get(item); return selectedItems.value.includes(value); }; (0, vue.watch)(pKey, () => { clear(); }); const objectsMap = (0, vue.computed)(() => { if (!pKey.value) return /* @__PURE__ */ new Map(); return new Map((0, vue.toValue)(allItems).map((item) => [get(item), item])); }); const getFromPrimaryKey = (value) => { if (!pKey.value) return void 0; return objectsMap.value.get(value); }; return { getFromPrimaryKey, resolvedItems: (0, vue.computed)(() => { if (!pKey.value) return selectedItems.value; const arr = []; selectedItems.value.forEach((item) => { const resolved = getFromPrimaryKey(item); if (resolved !== void 0) arr.push(resolved); }); return arr; }), isActivated, get, add, remove, clear, set, has, setAll }; }; var useItemExpansion = ({ allItems, primaryKey, expandedItems }) => { const utils = useItemTracker({ primaryKey, allItems, selectedItems: expandedItems }); const toggle = (item) => { if (utils.has(item)) utils.remove(item); else utils.add(item); }; return { ...utils, toggle }; }; var useTableKeyboardNavigation = ({ items, id }, events) => { const keyboardNavigation = (0, vue.inject)(require_keys.tableKeyboardNavigationKey, null); const shouldHeaderBeFocusable = (field) => !!(keyboardNavigation?.headerNavigation.value && field.sortable === true); const shouldRowBeFocusable = (0, vue.computed)(() => !!(keyboardNavigation?.rowNavigation.value && (0, vue.toValue)(items).length > 0)); const headerClicked = (field, event, isFooter = false) => { events.onHeadClicked({ key: field.key, field, event, isFooter }); }; const handleHeaderKeydown = (field, event, isFooter = false) => { const { target, code } = event; if (target && target.tagName !== "TH" && require_dom.getSafeDocument()?.activeElement === target) return; if (code === "Enter" || code === "NumpadEnter" || code === "Space") { event.preventDefault(); headerClicked(field, event, isFooter); } }; const handleRowKeydown = (item, itemIndex, event) => { const { target, code, shiftKey } = event; if (target && target.tagName !== "TR" && require_dom.getSafeDocument()?.activeElement === target) return; if (code === "Enter" || code === "NumpadEnter" || code === "Space") { event.preventDefault(); events.onRowClicked({ item, index: itemIndex, event }); return; } if (code === "ArrowDown" || code === "ArrowUp" || code === "Home" || code === "End") { event.preventDefault(); handleRowNavigation(code, shiftKey, itemIndex); } }; const handleRowNavigation = (code, shiftKey, currentIndex) => { const doc = require_dom.getSafeDocument(); const rows = doc === null ? [] : Array.from(doc.querySelectorAll(`#${(0, vue.toValue)(id)} tbody tr[tabindex]`)); if (rows.length === 0) return; let targetIndex = currentIndex; if (code === "ArrowDown") if (shiftKey) targetIndex = rows.length - 1; else targetIndex = Math.min(currentIndex + 1, rows.length - 1); else if (code === "ArrowUp") if (shiftKey) targetIndex = 0; else targetIndex = Math.max(currentIndex - 1, 0); else if (code === "End") targetIndex = rows.length - 1; else if (code === "Home") targetIndex = 0; if (targetIndex !== currentIndex && rows[targetIndex]) rows[targetIndex]?.focus(); }; const handleMiddleClick = (item, itemIndex, event) => { if (event.button === 1 && !filterEvent(event)) events.onRowMiddleClicked({ item, index: itemIndex, event }); }; return { shouldHeaderBeFocusable, headerClicked, handleHeaderKeydown, shouldRowBeFocusable, handleRowKeydown, handleMiddleClick }; }; //#endregion //#region src/components/BTable/BTableLite.vue?vue&type=script&setup=true&lang.ts var _hoisted_1$1 = { key: 0 }; var _hoisted_2$1 = { key: 0, class: "b-table-stacked-label" }; var _hoisted_3 = { class: "d-inline-flex flex-nowrap align-items-center gap-1" }; var _hoisted_4 = { key: 3 }; //#endregion //#region src/components/BTable/BTableLite.vue var BTableLite_default = /* @__PURE__ */ (0, vue.defineComponent)({ __name: "BTableLite", props: /* @__PURE__ */ (0, vue.mergeModels)({ align: { default: void 0 }, caption: { default: void 0 }, detailsTdClass: { default: void 0 }, fieldColumnClass: { type: [ Function, String, Object, Array ], default: void 0 }, fields: { default: () => [] }, footClone: { type: Boolean, default: false }, footRowVariant: { default: void 0 }, footVariant: { default: void 0 }, headRowVariant: { default: void 0 }, headVariant: { default: void 0 }, items: { default: () => [] }, labelStacked: { type: Boolean, default: false }, modelValue: { default: void 0 }, primaryKey: { type: [String, Function], default: void 0 }, tbodyClass: { default: void 0 }, tbodyTrAttrs: { type: [Function, Object], default: void 0 }, tbodyTrClass: { type: [ Function, String, Array, Object ], default: void 0 }, tfootClass: { default: void 0 }, tfootTrClass: { default: void 0 }, theadClass: { default: void 0 }, theadTrClass: { default: void 0 }, bordered: { type: Boolean, default: void 0 }, borderless: { type: Boolean, default: void 0 }, borderVariant: { default: void 0 }, captionTop: { type: Boolean, default: void 0 }, dark: { type: Boolean, default: void 0 }, fixed: { type: Boolean, default: void 0 }, hover: { type: Boolean, default: void 0 }, id: { default: void 0 }, noBorderCollapse: { type: Boolean, default: void 0 }, outlined: { type: Boolean, default: void 0 }, responsive: { type: [Boolean, String], default: void 0 }, small: { type: Boolean, default: void 0 }, stacked: { type: [Boolean, String], default: void 0 }, stickyHeader: { type: [ Boolean, String, Number ], default: void 0 }, striped: { type: Boolean, default: void 0 }, stripedColumns: { type: Boolean, default: void 0 }, variant: { default: void 0 }, tableAttrs: {}, tableClass: { default: void 0 } }, { "expandedItems": { default: () => [] }, "expandedItemsModifiers": {} }), emits: /* @__PURE__ */ (0, vue.mergeModels)([ "head-clicked", "row-clicked", "row-dblclicked", "row-contextmenu", "row-hovered", "row-unhovered", "row-middle-clicked" ], ["update:expandedItems"]), setup(__props, { expose: __expose, emit: __emit }) { const props = require_useDefaults.useDefaults(__props, "BTableLite"); const emit = __emit; const slots = (0, vue.useSlots)(); const expandedItems = (0, vue.useModel)(__props, "expandedItems"); const computedId = require_useId.useId(() => props.id); const expandedItemsController = useItemExpansion({ allItems: () => props.items, primaryKey: (0, vue.toRef)(() => props.primaryKey), expandedItems }); const keyboardController = useTableKeyboardNavigation({ items: () => props.items, id: computedId }, { onHeadClicked: (obj) => { emit("head-clicked", obj); }, onRowClicked: (obj) => { emit("row-clicked", obj); }, onRowMiddleClicked: (obj) => { emit("row-middle-clicked", obj); } }); const { fields: computedFields, total: computedFieldsTotal, showHeaders: showComputedHeaders } = useTableFieldsMapper({ fields: () => props.fields, items: () => props.items, stackedProps: { labelStacked: () => props.labelStacked, stacked: () => props.stacked } }); const calculatedFooterSlot = (key) => slots[`foot(${key})`] ? `foot(${key})` : slots["foot()"] ? "foot()" : slots[`head(${key})`] ? `head(${key})` : "head()"; const computedTableClasses = (0, vue.computed)(() => [props.tableClass, { [`align-${props.align}`]: props.align !== void 0 }]); const getFieldColumnClasses = (field) => [ field.class, field.thClass, { "b-table-sticky-column": field.stickyColumn }, props.fieldColumnClass ? typeof props.fieldColumnClass === "function" ? props.fieldColumnClass(field) : props.fieldColumnClass : null ]; const getFieldRowClasses = (field, tr) => [ field.class, typeof field.tdClass === "function" ? field.tdClass(getByFieldKey(tr, field), field.key, tr) : field.tdClass, (isTableItem(tr) ? tr._cellVariants?.[field.key] : false) ? `table-${tr._cellVariants?.[field.key]}` : null, { "b-table-sticky-column": field.stickyColumn } ]; const getRowClasses = (item, type) => props.tbodyTrClass ? typeof props.tbodyTrClass === "function" ? props.tbodyTrClass(item, type) : props.tbodyTrClass : null; const itemAttributes = (item, field) => field.tdAttr && typeof field.tdAttr === "function" ? field.tdAttr({ value: getByFieldKey(item, field), key: field.key, item }) : field.tdAttr; const callThAttr = (item, field, type) => field.thAttr && typeof field.thAttr === "function" ? field.thAttr({ value: getByFieldKey(item, field), key: field.key, item, type }) : field.thAttr; const callTbodyTrAttrs = (item, type) => props.tbodyTrAttrs ? typeof props.tbodyTrAttrs === "function" ? props.tbodyTrAttrs(item, type) : props.tbodyTrAttrs : null; const generateTableRowId = (primaryKeyValue) => `${computedId.value}__row_${primaryKeyValue}`; const getCellComponent = (field) => { if (field?.isRowHeader) return BTh_default; return BTd_default; }; const footerProps = (0, vue.computed)(() => ({ variant: props.footVariant ?? props.headVariant, class: props.tfootClass ?? props.theadClass })); const computedSimpleProps = (0, vue.computed)(() => ({ ...require_object.pick(props, bTableSimpleProps), tableClass: computedTableClasses.value, id: computedId.value })); __expose({ expansion: { ...expandedItemsController, expandedItems: (0, vue.readonly)(expandedItems) } }); return (_ctx, _cache) => { return (0, vue.openBlock)(), (0, vue.createBlock)(require_BTableSimple.BTableSimple_default, (0, vue.normalizeProps)((0, vue.guardReactiveProps)(computedSimpleProps.value)), { default: (0, vue.withCtx)(() => [ slots["table-colgroup"] ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("colgroup", _hoisted_1$1, [(0, vue.renderSlot)(_ctx.$slots, "table-colgroup", { fields: (0, vue.unref)(computedFields) })])) : (0, vue.createCommentVNode)("", true), (0, vue.withDirectives)((0, vue.createVNode)(BThead_default, { variant: (0, vue.unref)(props).headVariant, class: (0, vue.normalizeClass)((0, vue.unref)(props).theadClass) }, { default: (0, vue.withCtx)(() => [ (0, vue.renderSlot)(_ctx.$slots, "thead-top", { columns: (0, vue.unref)(computedFieldsTotal), fields: (0, vue.unref)(computedFields) }), (0, vue.createVNode)(BTr_default, { variant: (0, vue.unref)(props).headRowVariant, class: (0, vue.normalizeClass)((0, vue.unref)(props).theadTrClass) }, { default: (0, vue.withCtx)(() => [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)((0, vue.unref)(computedFields), (field) => { return (0, vue.openBlock)(), (0, vue.createBlock)(BTh_default, (0, vue.mergeProps)({ key: field.key, scope: field.scope, class: getFieldColumnClasses(field), title: field.headerTitle, variant: field.variant, abbr: field.headerAbbr, style: field.thStyle, tabindex: (0, vue.unref)(keyboardController).shouldHeaderBeFocusable(field) ? "0" : void 0 }, { ref_for: true }, callThAttr(null, field, "top"), { onClick: ($event) => (0, vue.unref)(keyboardController).headerClicked(field, $event), onKeydown: ($event) => (0, vue.unref)(keyboardController).handleHeaderKeydown(field, $event) }), { default: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, slots[`head(${field.key})`] ? `head(${field.key})` : "head()", { label: field.label, column: field.key, field, isFoot: false }, () => [(0, vue.createTextVNode)((0, vue.toDisplayString)((0, vue.unref)(getTableFieldHeadLabel)(field)), 1)])]), _: 2 }, 1040, [ "scope", "class", "title", "variant", "abbr", "style", "tabindex", "onClick", "onKeydown" ]); }), 128))]), _: 3 }, 8, ["variant", "class"]), slots["thead-sub"] ? ((0, vue.openBlock)(), (0, vue.createBlock)(BTr_default, { key: 0 }, { default: (0, vue.withCtx)(() => [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)((0, vue.unref)(computedFields), (field) => { return (0, vue.openBlock)(), (0, vue.createBlock)(BTd_default, { key: field.key, scope: "col", variant: field.variant, class: (0, vue.normalizeClass)([field.class, field.thClass]) }, { default: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "thead-sub", { items: (0, vue.unref)(props).items, fields: (0, vue.unref)(computedFields), field }, () => [(0, vue.createTextVNode)((0, vue.toDisplayString)(field.label), 1)])]), _: 2 }, 1032, ["variant", "class"]); }), 128))]), _: 3 })) : (0, vue.createCommentVNode)("", true) ]), _: 3 }, 8, ["variant", "class"]), [[vue.vShow, (0, vue.unref)(showComputedHeaders)]]), (0, vue.createVNode)(BTbody_default, { class: (0, vue.normalizeClass)((0, vue.unref)(props).tbodyClass) }, { default: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "custom-body", { fields: (0, vue.unref)(computedFields), items: (0, vue.unref)(props).items, columns: (0, vue.unref)(computedFieldsTotal) }, () => [ !(0, vue.unref)(props).stacked && slots["top-row"] ? ((0, vue.openBlock)(), (0, vue.createBlock)(BTr_default, (0, vue.mergeProps)({ key: 0, class: getRowClasses(null, "row-top") }, callTbodyTrAttrs(null, "row-top")), { default: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "top-row", { columns: (0, vue.unref)(computedFieldsTotal), fields: (0, vue.unref)(computedFields) })]), _: 3 }, 16, ["class"])) : (0, vue.createCommentVNode)("", true), ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)((0, vue.unref)(props).items, (item, itemIndex) => { return (0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: (0, vue.unref)(props).primaryKey && (0, vue.unref)(isTableItem)(item) && (0, vue.unref)(getWithGetter)(item, (0, vue.unref)(props).primaryKey) ? (0, vue.unref)(getWithGetter)(item, (0, vue.unref)(props).primaryKey) : itemIndex }, [(0, vue.createVNode)(BTr_default, (0, vue.mergeProps)({ id: (0, vue.unref)(props).primaryKey && (0, vue.unref)(isTableItem)(item) && (0, vue.unref)(getWithGetter)(item, (0, vue.unref)(props).primaryKey) ? generateTableRowId((0, vue.unref)(getWithGetter)(item, (0, vue.unref)(props).primaryKey)) : void 0, class: getRowClasses(item, "row"), variant: (0, vue.unref)(isTableItem)(item) ? item._rowVariant : void 0, tabindex: (0, vue.unref)(keyboardController).shouldRowBeFocusable.value ? "0" : void 0 }, { ref_for: true }, callTbodyTrAttrs(item, "row"), { onClick: ($event) => !(0, vue.unref)(filterEvent)($event) && emit("row-clicked", { item, index: itemIndex, event: $event }), onDblclick: ($event) => !(0, vue.unref)(filterEvent)($event) && emit("row-dblclicked", { item, index: itemIndex, event: $event }), onContextmenu: ($event) => !(0, vue.unref)(filterEvent)($event) && emit("row-contextmenu", { item, index: itemIndex, event: $event }), onMouseenter: ($event) => !(0, vue.unref)(filterEvent)($event) && emit("row-hovered", { item, index: itemIndex, event: $event }), onMouseleave: ($event) => !(0, vue.unref)(filterEvent)($event) && emit("row-unhovered", { item, index: itemIndex, event: $event }), onMousedown: ($event) => (0, vue.unref)(keyboardController).handleMiddleClick(item, itemIndex, $event), onKeydown: ($event) => (0, vue.unref)(keyboardController).handleRowKeydown(item, itemIndex, $event) }), { default: (0, vue.withCtx)(() => [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)((0, vue.unref)(computedFields), (field) => { return (0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)(getCellComponent(field)), (0, vue.mergeProps)({ key: field.key, variant: ((0, vue.unref)(isTableItem)(item) ? item._cellVariants?.[field.key] : false) ? null : field.variant, class: getFieldRowClasses(field, item) }, { ref_for: true }, itemAttributes(item, field)), { default: (0, vue.withCtx)(() => [(0, vue.unref)(props).stacked && (0, vue.unref)(props).labelStacked ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("label", _hoisted_2$1, (0, vue.toDisplayString)((0, vue.unref)(getTableFieldHeadLabel)(field)), 1)) : (0, vue.createCommentVNode)("", true), (0, vue.renderSlot)(_ctx.$slots, slots[`cell(${field.key})`] ? `cell(${field.key})` : "cell()", { value: (0, vue.unref)(formatItem)(item, field), unformatted: (0, vue.unref)(getByFieldKey)(item, field), index: itemIndex, item, field, items: (0, vue.unref)(props).items, toggleExpansion: () => (0, vue.unref)(expandedItemsController).toggle(item), expansionShowing: (0, vue.unref)(expandedItemsController).has(item) }, () => [!slots[`cell(${field.key})`] && !slots["cell()"] ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 0 }, [(0, vue.createTextVNode)((0, vue.toDisplayString)((0, vue.unref)(formatItem)(item, field)), 1)], 64)) : (0, vue.createCommentVNode)("", true)])]), _: 2 }, 1040, ["variant", "class"]); }), 128))]), _: 2 }, 1040, [ "id", "class", "variant", "tabindex", "onClick", "onDblclick", "onContextmenu", "onMouseenter", "onMouseleave", "onMousedown", "onKeydown" ]), (0, vue.unref)(expandedItemsController).has(item) && slots["row-expansion"] ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 0 }, [(0, vue.createVNode)(BTr_default, { "aria-hidden": "true", role: "presentation", class: "d-none" }), (0, vue.createVNode)(BTr_default, (0, vue.mergeProps)({ class: getRowClasses(item, "row-expansion"), variant: (0, vue.unref)(isTableItem)(item) ? item._rowVariant : void 0 }, { ref_for: true }, callTbodyTrAttrs(item, "row-expansion")), { default: (0, vue.withCtx)(() => [(0, vue.createVNode)(BTd_default, { colspan: (0, vue.unref)(computedFieldsTotal), class: (0, vue.normalizeClass)(__props.detailsTdClass) }, { default: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "row-expansion", { item, toggleExpansion: () => (0, vue.unref)(expandedItemsController).toggle(item), fields: (0, vue.unref)(computedFields), index: itemIndex })]), _: 2 }, 1032, ["colspan", "class"])]), _: 2 }, 1040, ["class", "variant"])], 64)) : (0, vue.createCommentVNode)("", true)], 64); }), 128)), !(0, vue.unref)(props).stacked && slots["bottom-row"] ? ((0, vue.openBlock)(), (0, vue.createBlock)(BTr_default, (0, vue.mergeProps)({ key: 1, class: ["bottom-row", getRowClasses(null, "row-bottom")] }, callTbodyTrAttrs(null, "row-bottom")), { default: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "bottom-row", { columns: (0, vue.unref)(computedFieldsTotal), fields: (0, vue.unref)(computedFields) })]), _: 3 }, 16, ["class"])) : (0, vue.createCommentVNode)("", true) ])]), _: 3 }, 8, ["class"]), (0, vue.unref)(props).footClone ? ((0, vue.openBlock)(), (0, vue.createBlock)(BTfoot_default, (0, vue.normalizeProps)((0, vue.mergeProps)({ key: 1 }, footerProps.value)), { default: (0, vue.withCtx)(() => [(0, vue.createVNode)(BTr_default, { variant: (0, vue.unref)(props).footRowVariant ?? (0, vue.unref)(props).headRowVariant, class: (0, vue.normalizeClass)((0, vue.unref)(props).tfootTrClass ?? (0, vue.unref)(props).theadTrClass) }, { default: (0, vue.withCtx)(() => [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)((0, vue.unref)(computedFields), (field) => { return (0, vue.openBlock)(), (0, vue.createBlock)(BTh_default, (0, vue.mergeProps)({ key: field.key, scope: "col", class: getFieldColumnClasses(field), title: field.headerTitle, abbr: field.headerAbbr, style: field.thStyle, variant: field.variant, tabindex: (0, vue.unref)(keyboardController).shouldHeaderBeFocusable(field) ? "0" : void 0 }, { ref_for: true }, callThAttr(null, field, "bottom"), { onClick: ($event) => (0, vue.unref)(keyboardController).headerClicked(field, $event, true), onKeydown: ($event) => (0, vue.unref)(keyboardController).handleHeaderKeydown(field, $event, true) }), { default: (0, vue.withCtx)(() => [(0, vue.createElementVNode)("div", _hoisted_3, [(0, vue.createElementVNode)("div", null, [(0, vue.renderSlot)(_ctx.$slots, calculatedFooterSlot(field.key), { label: field.label, column: field.key, field, isFoot: true }, () => [(0, vue.createTextVNode)((0, vue.toDisplayString)((0, vue.unref)(getTableFieldHeadLabel)(field)), 1)])])])]), _: 2 }, 1040, [ "class", "title", "abbr", "style", "variant", "tabindex", "onClick", "onKeydown" ]); }), 128))]), _: 3 }, 8, ["variant", "class"])]), _: 3 }, 16)) : slots["custom-foot"] ? ((0, vue.openBlock)(), (0, vue.createBlock)(BTfoot_default, (0, vue.normalizeProps)((0, vue.mergeProps)({ key: 2 }, footerProps.value)), { default: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "custom-foot", { fields: (0, vue.unref)(computedFields), items: (0, vue.unref)(props).items, columns: (0, vue.unref)(computedFieldsTotal) })]), _: 3 }, 16)) : (0, vue.createCommentVNode)("", true), slots["table-caption"] || (0, vue.unref)(props).caption ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("caption", _hoisted_4, [(0, vue.renderSlot)(_ctx.$slots, "table-caption", {}, () => [(0, vue.createTextVNode)((0, vue.toDisplayString)((0, vue.unref)(props).caption), 1)])])) : (0, vue.createCommentVNode)("", true) ]), _: 3 }, 16); }; } }); //#endregion //#region src/composables/useTableHelpers.ts var useTableMapper = ({ fields, items, stackedProps, provider, events, pagination }) => { const sortByModelResolved = (0, vue.readonly)((0, vue.toRef)(pagination.sort.by)); const isSortableResolved = (0, vue.readonly)((0, vue.toRef)(pagination.sort.isSortable)); const filterResolved = (0, vue.readonly)((0, vue.toRef)(pagination.filter.filter)); const usesProviderResolved = (0, vue.readonly)((0, vue.toRef)(provider.usesProvider)); const isFilterableTable = (0, vue.computed)(() => filterResolved.value !== void 0); const computedFields = (0, vue.computed)(() => (0, vue.toValue)(fields).map((el) => { if (!isTableField(el)) { const label = require_stringUtils.startCase(el); return { key: el, label, tdAttr: getDataLabelAttr({ stacked: (0, vue.toValue)(stackedProps.stacked), labelStacked: (0, vue.toValue)(stackedProps.labelStacked) }, label) }; } const value = sortByModelResolved.value?.find((sb) => el.key === sb.key); const sortValue = !el.sortable || isSortableResolved.value === false ? void 0 : value === void 0 ? "none" : value.order === "desc" ? "descending" : value.order === "asc" ? "ascending" : "none"; return { ...el, thAttr: { "aria-sort": sortValue, ...el.thAttr }, thClass: [el.thClass, { "b-table-sort-icon-left": (0, vue.toValue)(pagination.sort.iconLeft) && sortValue !== void 0 }] }; })); const getFormatter = (value) => typeof value.sortByFormatted === "function" ? value.sortByFormatted : value.formatter; const getStringValue = (ob, key) => { if (!isTableItem(ob)) return String(ob); const sortField = computedFields.value.find((el) => { if (isTableField(el)) return el.key === key; return false; }); const val = isTableField(sortField) && sortField.accessor ? getWithGetter(ob, sortField.accessor) : getWithGetter(ob, key); if (isTableField(sortField) && !!sortField.sortByFormatted) { const formatter = getFormatter(sortField); if (formatter) return String(formatItem(ob, { ...sortField, formatter })); } return typeof val === "object" && val !== null ? JSON.stringify(val) : val?.toString() ?? ""; }; const fieldByKey = (0, vue.computed)(() => { const map = /* @__PURE__ */ new Map(); for (const f of computedFields.value) if (isTableField(f)) map.set(f.key, f); return map; }); const computedItems = (0, vue.computed)(() => { const filterableValue = (0, vue.toValue)(pagination.filter.filterable); const filterFunctionValue = (0, vue.unref)(pagination.filter.filterFunction); const itemsValue = (0, vue.toValue)(items); const sortByItems = sortByModelResolved.value?.filter((el) => !!el.order); const mapItem = (item) => { if (typeof item === "object" && item !== null && Object.keys(item).some((key) => key.includes("."))) { let newItem = {}; for (const key in item) if (key.includes(".")) newItem = require_object.set(newItem, key, item[key]); else newItem[key] = item[key]; return newItem; } return item; }; const filterItem = (item) => { if (!isTableItem(item)) return true; return Object.entries(item).some(([key, val]) => { if (val === null || val === void 0 || key[0] === "_" || !filterableValue?.includes(key) && !!filterableValue?.length) return false; if (typeof filterFunctionValue === "function") return filterFunctionValue(item, filterResolved.value); const realVal = () => { const filterField = computedFields.value.find((el) => { if (isTableField(el)) return el.key === key; return false; }); if (isTableField(filterField) && !!filterField.filterByFormatted) { const formatter = getFormatter(filterField); if (formatter) return String(formatter({ value: val, key: String(filterField.key), item })); } return typeof val === "object" ? JSON.stringify(Object.values(val)) : val.toString(); }; return realVal().toLowerCase().includes(filterResolved.value?.toLowerCase() ?? ""); }); }; const noProviderFilteringValue = (0, vue.toValue)(provider.noProviderFiltering); const mappedItems = itemsValue.reduce((acc, val) => { const item = mapItem(val); if (!(isFilterableTable.value && (!usesProviderResolved.value || noProviderFilteringValue)) || filterItem(item)) acc.push(item); return acc; }, []); if (sortByItems?.length && (isSortableResolved.value === true && !usesProviderResolved.value && !(0, vue.toValue)(pagination.sort.noLocalSorting) || isSortableResolved.value === true && usesProviderResolved.value && (0, vue.toValue)(provider.noProviderSorting))) { const sortCompareValue = (0, vue.unref)(pagination.sort.sortCompare); return mappedItems.sort((a, b) => { for (let i = 0; i < sortByItems.length; i++) { const value = sortByItems[i]; if (value === void 0) continue; const { key, order } = value; const comparer = fieldByKey.value.get(key)?.sortCompare || sortCompareValue; const comparison = comparer ? comparer(a, b, key) : getStringValue(a, key).localeCompare(getStringValue(b, key), void 0, { numeric: true }); if (comparison !== 0) return order === "asc" ? comparison : -comparison; } return 0; }); } return mappedItems; }); const computedDisplayItems = (0, vue.computed)(() => { const perPageNumber = (0, vue.toValue)(pagination.perPage); const currentPageNumber = (0, vue.toValue)(pagination.currentPage); if (Number.isNaN(perPageNumber) || usesProviderResolved.value && !(0, vue.toValue)(provider.noProviderPaging)) return computedItems.value; return computedItems.value.slice((currentPageNumber - 1) * (perPageNumber || Number.POSITIVE_INFINITY), currentPageNumber * (perPageNumber || Number.POSITIVE_INFINITY)); }); (0, vue.watch)(filterResolved, () => { pagination.currentPage.value = 1; }); (0, vue.watch)(computedDisplayItems, (v) => { events.onChange([...v]); }); return { items: computedItems, displayItems: computedDisplayItems, getStringValue, fields: computedFields, isFilterableTable }; }; var useTableKeyboardNavigationInjector = ({ isSortable, selectable, noSelectOnClick }) => { (0, vue.provide)(require_keys.tableKeyboardNavigationKey, { rowNavigation: (0, vue.computed)(() => !!((0, vue.toValue)(selectable) && !(0, vue.toValue)(noSelectOnClick))), headerNavigation: (0, vue.computed)(() => !!(0, vue.toValue)(isSortable)) }); }; var useTableSelectedItems = ({ selectable, selectMode, selectedItems, events, primaryKey, allItems }) => { const selectableResolved = (0, vue.readonly)((0, vue.toRef)(selectable)); const selectModeResolved = (0, vue.readonly)((0, vue.toRef)(selectMode)); const allItemsResolved = (0, vue.computed)(() => (0, vue.toValue)(allItems)); const utils = useItemTracker({ allItems: allItemsResolved, primaryKey, selectedItems }); (0, vue.watch)(selectedItems, (newValue, oldValue) => { Array.from(oldValue).filter((item) => !newValue.includes(item)).forEach((item) => { events.onRowUnselected(item); }); Array.from(newValue).filter((item) => !oldValue.includes(item)).forEach((item) => { events.onRowSelected(item); }); }); const handleRowSelection = ({ item, index, shiftClicked = false, ctrlClicked = false, metaClicked = false }) => { if (!selectableResolved.value) return; if (selectModeResolved.value === "single" || selectModeResolved.value === "multi") { if (shiftClicked || ctrlClicked) return; if (utils.has(item)) utils.remove(item); else if (selectModeResolved.value === "single") utils.set([item]); else utils.add(item); } else if (ctrlClicked || metaClicked) if (utils.has(item)) utils.remove(item); else utils.add(item); else if (shiftClicked) { const lastSelectedItem = selectedItems.value[selectedItems.value.length - 1]; const lastSelectedIndex = allItemsResolved.value.findIndex((i) => utils.get(i) === lastSelectedItem); if (lastSelectedIndex === -1) { utils.set([item]); return; } const selectStartIndex = Math.min(lastSelectedIndex, index); const selectEndIndex = Math.max(lastSelectedIndex, index); const items = allItemsResolved.value.slice(selectStartIndex, selectEndIndex + 1); utils.set(items); } else utils.set([item]); }; return { ...utils, handleRowSelection, clear: () => { if (!selectableResolved.value) return; utils.clear(); }, setAll: () => { if (!selectableResolved.value || selectModeResolved.value === "single") return; utils.setAll(); }, add: (item) => { if (!selectableResolved.value || utils.has(item)) return; if (selectModeResolved.value === "single") utils.set([item]); else utils.add(item); }, remove: (item) => { if (!selectableResolved.value) return; utils.remove(item); }, has: (item) => { if (!selectableResolved.value) return false; return utils.has(item); } }; }; var useTableProvider = ({ items, provider, busy, currentPage, debounce, perPage, noProvider, noProviderFiltering, noProviderPaging, noProviderSorting, filter, sortBy, events }) => { const providerResolved = (0, vue.readonly)((0, vue.toRef)(provider)); const currentPageResolved = (0, vue.readonly)((0, vue.toRef)(currentPage)); const perPageResolved = (0, vue.readonly)((0, vue.toRef)(perPage)); const sortByResolved = (0, vue.readonly)((0, vue.toRef)(sortBy)); const filterResolved = (0, vue.readonly)((0, vue.toRef)(filter)); const usesProvider = (0, vue.computed)(() => providerResolved.value !== void 0); let abortController = null; const callItemsProvider = async () => { if (!usesProvider.value || providerResolved.value === void 0) return; if (abortController) abortController.abort(); abortController = new AbortController(); const { signal } = abortController; busy.value = true; try { const response = providerResolved.value({ currentPage: currentPageResolved.value, filter: filterResolved.value, sortBy: sortByResolved.value, perPage: perPageResolved.value, signal }); const returnValue = response instanceof Promise ? await response : response; if (signal.aborted) return; if (returnValue === void 0) return; items.value = returnValue; } catch (error) { if (error instanceof Error && error.name === "AbortError") return; throw error; } finally { if (!signal.aborted) busy.value = false; } }; const debouncedCallItemsProvider = require_debounce.useDebounceFn(callItemsProvider, debounce.wait, { maxWait: debounce.maxWait }); const providerPropsWatch = async (prop, val, oldVal) => { if (require_object.deepEqual(val, oldVal)) return; const inNoProvider = (key) => (0, vue.toValue)(noProvider)?.includes(key) === true; const noProvideWhenPaging = (prop === "currentPage" || prop === "perPage") && (inNoProvider("paging") || (0, vue.toValue)(noProviderPaging) === true); const noProvideWhenFiltering = prop === "filter" && (inNoProvider("filtering") || (0, vue.toValue)(noProviderFiltering) === true); const noProvideWhenSorting = (prop === "sortBy" || prop === "sortDesc") && (inNoProvider("sorting") || (0, vue.toValue)(noProviderSorting) === true); if (noProvideWhenPaging || noProvideWhenFiltering || noProvideWhenSorting) return; if (usesProvider.value === true) await debouncedCallItemsProvider(); if (!(prop === "currentPage" || prop === "perPage")) events.onFiltered(); }; (0, vue.watch)(filterResolved, async (filter, oldFilter) => { await providerPropsWatch("filter", filter, oldFilter); }); (0, vue.watch)(currentPageResolved, async (val, oldVal) => { await providerPropsWatch("currentPage", val, oldVal); }); (0, vue.watch)(perPageResolved, async (val, oldVal) => { await providerPropsWatch("perPage", val, oldVal); }); (0, vue.watch)(sortByResolved, async (val, oldVal) => { await providerPropsWatch("sortBy", val, oldVal); }, { deep: true }); (0, vue.watch)(providerResolved, async (newValue) => { if (newValue === void 0) { items.value = []; return; } await callItemsProvider(); }); (0, vue.onMounted)(async () => { await callItemsProvider(); }); return { usesProvider, callItemsProvider }; }; var useTableSort = ({ fields, sortBy, initialSortDirection, multisort, mustSort, events }) => { const isSortable = (0, vue.computed)(() => sortBy.value !== void 0 || (0, vue.toValue)(fields).some((field) => typeof field === "object" && field !== null && field.sortable === true)); const handleFieldSorting = (field) => { if (!isSortable.value) return; const fieldKey = typeof field === "object" && field !== null ? field.key : field; const fieldSortable = typeof field === "object" && field !== null ? field.sortable : false; if (!(isSortable.value === true && fieldSortable === true)) return; const getLastSortDirection = () => { return [...sortBy.value ?? []].reverse().find((sort) => sort.order !== void 0 && sort.key !== fieldKey)?.order ?? "asc"; }; const getInitialSortDirection = () => { if (typeof field === "object" && field !== null && field.initialSortDirection) { if (field.initialSortDirection === "last") return getLastSortDirection(); return field.initialSortDirection; } const initialSortDirectionValue = (0, vue.toValue)(initialSortDirection); if (initialSortDirectionValue) { if (initialSortDirectionValue === "last") return getLastSortDirection(); return initialSortDirectionValue; } return "asc"; }; const resolveOrder = (val) => { const mustSortValue = (0, vue.toValue)(mustSort); if (val === void 0) return getInitialSortDirection(); const initial = getInitialSortDirection(); const must = mustSortValue === true || !!mustSortValue && mustSortValue.includes(fieldKey); if (val === "asc") { if (initial === "desc") return must ? "desc" : void 0; return "desc"; } if (val === "desc") { if (initial === "desc") return "asc"; return must ? "asc" : void 0; } }; const index = sortBy.value?.findIndex((el) => el.key === fieldKey) ?? -1; const originalValue = sortBy.value?.[index]; const updatedValue = index === -1 || !originalValue ? { key: fieldKey, order: getInitialSortDirection() } : { ...originalValue }; /** * @returns the updated value to emit for sorted */ const handleMultiSort = () => { const tmp = [...sortBy.value ?? []]; const val = updatedValue; if (index === -1) tmp.push(val); else { const order = resolveOrder(val.order); if (order) { val.order = order; tmp.splice(index, 1, val); } else { val.order = void 0; tmp.splice(index, 1); } } sortBy.value = tmp; return val; }; /** * @returns the updated value to emit for sorted */ const handleSingleSort = () => { const order = index === -1 ? updatedValue.order : resolveOrder(updatedValue.order); const val = { ...updatedValue, order }; sortBy.value = order ? [val] : []; return val; }; events.onSorted((0, vue.toValue)(multisort) === true ? handleMultiSort() : handleSingleSort()); }; return { isSortable, handleFieldSorting }; }; //#endregion //#region src/components/BTable/BTable.vue?vue&type=script&setup=true&lang.