'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var core = require('@vue-layout/core'); var vue = require('vue'); /* * Copyright (c) 2023. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ function boolableToObject(input) { if (typeof input === 'boolean') { return {}; } return input; } /* * Copyright (c) 2022. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ exports.Component = void 0; (function(Component) { Component["List"] = "list"; Component["ListFooter"] = "listFooter"; Component["ListHeader"] = "listHeader"; Component["ListItem"] = "listItem"; Component["ListBody"] = "listBody"; Component["ListLoading"] = "listLoading"; Component["ListNoMore"] = "listNoMore"; })(exports.Component || (exports.Component = {})); exports.SlotName = void 0; (function(SlotName) { SlotName["DEFAULT"] = "default"; SlotName["FOOTER"] = "footer"; SlotName["HEADER"] = "header"; SlotName["BODY"] = "body"; SlotName["LOADING"] = "loading"; SlotName["NO_MORE"] = "noMore"; SlotName["ITEM"] = "item"; SlotName["ITEM_ACTIONS"] = "itemActions"; SlotName["ITEM_ACTIONS_EXTRA"] = "itemActionsExtra"; })(exports.SlotName || (exports.SlotName = {})); function buildListBaseOptions(options, component, defaults) { defaults = defaults || {}; const { buildOrFail } = core.createOptionBuilder(component); return { slotItems: options.slotItems || {}, slotProps: buildOrFail({ key: 'slotProps', value: options.slotProps, alt: defaults.slotProps || {} }), slotPropsBuilt: options.slotPropsBuilt, tag: buildOrFail({ key: 'tag', value: options.tag, alt: defaults.tag || 'div' }), class: buildOrFail({ key: 'class', value: options.class, alt: defaults.class || [] }), props: buildOrFail({ key: 'props', value: options.props, alt: defaults.props || {} }), total: options.total, load: options.load, meta: options.meta || {}, busy: options.busy, itemId: options.itemId, itemKey: options.itemKey, onCreated: options.onCreated, onUpdated: options.onUpdated, onDeleted: options.onDeleted }; } const buildFilterFn = (item, itemId, itemKey)=>{ let filterFn; if (itemId) { filterFn = (el)=>itemId(el) === itemId(item); } if (itemKey) { filterFn = (el)=>{ if (typeof itemKey === 'function') { return el[itemKey(el)] === item[itemKey(item)]; } return el[itemKey] === item[itemKey]; }; } if (!filterFn && core.isObject(item) && core.hasOwnProperty(item, 'id')) { filterFn = (el)=>el['id'] === item['id']; } return filterFn; }; function buildListBaseSlotProps(ctx) { const props = {}; if (typeof ctx.busy !== 'undefined') { props.busy = vue.unref(ctx.busy); } if (typeof ctx.meta !== 'undefined') { props.meta = ctx.meta; } if (typeof ctx.total !== 'undefined') { props.total = vue.unref(ctx.total); } const incrTotal = ()=>{ if (typeof ctx.total === 'undefined') { return; } if (vue.isRef(ctx.total)) { ctx.total.value++; props.total = ctx.total.value; } }; const decrTotal = ()=>{ if (typeof ctx.total === 'undefined') { return; } if (vue.isRef(ctx.total)) { ctx.total.value--; props.total = ctx.total.value; } }; if (typeof ctx.load === 'function') { props.load = (meta)=>{ if (!vue.isRef(ctx.busy)) { return ctx.load(meta); } ctx.busy.value = true; const output = ctx.load(meta); if (core.isPromise(output)) { return output.finally(()=>{ if (vue.isRef(ctx.busy)) { ctx.busy.value = false; } }); } ctx.busy.value = false; return output; }; } props.created = (item)=>{ if (typeof ctx.data === 'undefined') { if (typeof ctx.onCreated === 'function') { ctx.onCreated(item); } incrTotal(); return; } const data = vue.unref(ctx.data); if (Array.isArray(data)) { const filterFn = buildFilterFn(item, ctx.itemId, ctx.itemKey); if (filterFn) { const index = core.findIndexOfMaybeRefArray(ctx.data, filterFn); if (index === -1) { core.pushMaybeRefArrayValue(ctx.data, item); incrTotal(); if (typeof ctx.onCreated === 'function') { ctx.onCreated(item); } } } } else { incrTotal(); if (typeof ctx.onCreated === 'function') { ctx.onCreated(item); } } }; props.deleted = (item)=>{ if (typeof ctx.data === 'undefined') { if (typeof ctx.onDeleted === 'function' && item) { ctx.onDeleted(item); } decrTotal(); return; } const data = vue.unref(ctx.data); if (Array.isArray(data)) { if (item) { const filterFn = buildFilterFn(item, ctx.itemId, ctx.itemKey); if (filterFn) { const index = core.findIndexOfMaybeRefArray(ctx.data, filterFn); if (index !== -1) { core.spliceMaybeRefArray(ctx.data, index, 1); decrTotal(); if (typeof ctx.onDeleted === 'function') { if (item) { ctx.onDeleted(item); } else { ctx.onDeleted(data[index]); } } } } } } else { decrTotal(); if (typeof ctx.onDeleted === 'function') { if (item) { ctx.onDeleted(item); } else { ctx.onDeleted(data); } } } }; props.updated = (item)=>{ if (typeof ctx.data === 'undefined') { if (typeof ctx.onUpdated === 'function') { ctx.onUpdated(item); } return; } const data = vue.unref(ctx.data); if (Array.isArray(data)) { const filterFn = buildFilterFn(item, ctx.itemId, ctx.itemKey); if (filterFn) { const index = core.findIndexOfMaybeRefArray(ctx.data, filterFn); if (index !== -1) { core.extendMaybeRefArrayValue(ctx.data, index, item); if (typeof ctx.onUpdated === 'function') { ctx.onUpdated(item); // todo: extend with data } } } } else { core.extendMaybeRefObject(ctx.data, item); if (typeof ctx.onUpdated === 'function') { if (item) { ctx.onUpdated(item); // todo: extend with data } else { ctx.onUpdated(data); } } } }; return props; } function buildListFooterOptions(input) { const options = buildListBaseOptions(input, exports.Component.ListFooter, { class: 'list-footer' }); const { buildOrFail } = core.createOptionBuilder(exports.Component.ListHeader); return { ...options, content: buildOrFail({ key: 'content', value: input.content, alt: [] }) }; } function buildListFooter(input) { input = input || {}; const options = buildListFooterOptions(input); let slotProps; if (options.slotPropsBuilt) { slotProps = options.slotProps; } else { slotProps = { ...buildListBaseSlotProps(options), ...options.slotProps }; } let children = []; if (core.hasNormalizedSlot(exports.SlotName.FOOTER, options.slotItems)) { children = [ core.normalizeSlot(exports.SlotName.FOOTER, slotProps, options.slotItems) ]; } else if (options.content) { if (typeof options.content === 'function') { children = [ options.content(slotProps) ]; } else { children = [ options.content ]; } } if (children.length > 0) { return vue.h(options.tag, vue.mergeProps({ class: options.class }, options.props), [ children ]); } return []; } function buildListHeaderOptions(input) { const options = buildListBaseOptions(input, exports.Component.ListHeader, { class: 'list-header' }); const { buildOrFail } = core.createOptionBuilder(exports.Component.ListHeader); return { ...options, content: buildOrFail({ key: 'content', value: input.content, alt: [] }) }; } function buildListHeader(input) { input = input || {}; const options = buildListHeaderOptions(input); let slotProps; if (options.slotPropsBuilt) { slotProps = options.slotProps; } else { slotProps = { ...buildListBaseSlotProps(options), ...options.slotProps }; } let content = []; if (core.hasNormalizedSlot(exports.SlotName.HEADER, options.slotItems)) { content = [ core.normalizeSlot(exports.SlotName.HEADER, slotProps, options.slotItems) ]; } else if (options.content) { if (typeof options.content === 'function') { content = [ options.content(slotProps) ]; } else { content = [ options.content ]; } } if (content.length > 0) { return vue.h(options.tag, vue.mergeProps({ class: options.class }, options.props), [ content ]); } return []; } function buildListItemOptions(input) { const options = buildListBaseOptions(input, exports.Component.ListItem, { class: 'list-item', tag: 'li' }); const { buildOrFail } = core.createOptionBuilder(exports.Component.ListItem); return { ...options, data: input.data, content: input.content, index: input.index, icon: buildOrFail({ key: 'icon', value: input.icon, alt: true }), iconTag: buildOrFail({ key: 'iconTag', value: input.iconTag, alt: 'i' }), iconClass: buildOrFail({ key: 'iconClass', value: input.iconClass, alt: [] }), iconProps: input.iconProps || {}, iconWrapper: buildOrFail({ key: 'iconWrapper', value: input.iconWrapper, alt: true }), iconWrapperClass: buildOrFail({ key: 'iconWrapperClass', value: input.iconWrapperClass, alt: [] }), iconWrapperTag: buildOrFail({ key: 'iconWrapperTag', value: input.iconWrapperTag, alt: 'div' }), text: buildOrFail({ key: 'text', value: input.text, alt: true }), textContent: input.textContent, textPropName: buildOrFail({ key: 'textPropName', value: input.textPropName, alt: 'name' }), textWrapper: buildOrFail({ key: 'textWrapper', value: input.textWrapper, alt: true }), textWrapperClass: buildOrFail({ key: 'textWrapperClass', value: input.textWrapperClass, alt: [] }), textWrapperTag: buildOrFail({ key: 'textWrapperTag', value: input.textWrapperTag, alt: 'div' }), actions: buildOrFail({ key: 'actions', value: input.actions, alt: true }), actionsContent: buildOrFail({ key: 'actionsContent', value: input.actionsContent, alt: [] }), actionsWrapper: buildOrFail({ key: 'actionsWrapper', value: input.actionsWrapper, alt: true }), actionsWrapperClass: buildOrFail({ key: 'actionsWrapperClass', value: input.actionsWrapperClass, alt: [] }), actionsWrapperTag: buildOrFail({ key: 'actionsWrapperTag', value: input.actionsWrapperTag, alt: 'div' }) }; } function maybeWrapContent(input, ctx) { if (!ctx.wrap) { return input; } return vue.h(ctx.tag, { class: ctx.class }, [ input ]); } function buildListItem(input) { const options = buildListItemOptions(input); const data = vue.unref(options.data); const overrideUpdatedFn = (fn, item)=>{ if (core.isObject(item) && core.isObject(data)) { options.data = core.setMaybeRefValue(options.data, core.merge(item || {}, data)); } else if (item) { options.data = core.setMaybeRefValue(options.data, item); } return fn(vue.unref(options.data)); }; let slotProps; if (options.slotPropsBuilt) { const { updated, deleted, ...original } = options.slotProps; slotProps = { ...original, data, index: options.index }; if (updated) { slotProps.updated = (item)=>overrideUpdatedFn(updated, item); } if (deleted) { slotProps.deleted = (item)=>deleted(item || data); } } else { const { updated, deleted, ...original } = buildListBaseSlotProps({ ...options, data: options.data }); slotProps = { ...original, data, index: options.index }; if (updated) { slotProps.updated = (item)=>overrideUpdatedFn(updated, item); } if (deleted) { slotProps.deleted = (item)=>deleted(item || data); } } const renderContent = (content)=>vue.h(options.tag, vue.mergeProps({ key: options.index }, { class: options.class }, options.props), [ content || [] ]); const children = {}; if (core.hasNormalizedSlot(exports.SlotName.ITEM, options.slotItems)) { children.slot = core.normalizeSlot(exports.SlotName.ITEM, slotProps, options.slotItems); } else { if (options.icon) { children.icon = maybeWrapContent(vue.h(options.iconTag, vue.mergeProps({ class: options.iconClass }, options.iconProps)), { wrap: options.iconWrapper, tag: options.iconWrapperTag, class: options.iconWrapperClass }); } if (options.text) { let text; if (options.textContent) { text = core.evaluateFnOrValue(options.textContent, data, slotProps); } else if (options.textPropName && core.isObject(data) && core.hasOwnProperty(data, options.textPropName)) { text = data[options.textPropName]; } if (text) { children.text = maybeWrapContent(text, { wrap: options.textWrapper, tag: options.textWrapperTag, class: options.textWrapperClass }); } } let actions; if (options.actions) { if (core.hasNormalizedSlot(exports.SlotName.ITEM_ACTIONS, options.slotItems)) { actions = [ core.normalizeSlot(exports.SlotName.ITEM_ACTIONS, slotProps, options.slotItems) ]; } else if (options.actionsContent) { actions = core.evaluateFnOrValue(options.actionsContent, data, slotProps); } if (core.hasNormalizedSlot(exports.SlotName.ITEM_ACTIONS_EXTRA, options.slotItems)) { actions = [ actions, core.normalizeSlot(exports.SlotName.ITEM_ACTIONS_EXTRA, slotProps, options.slotItems) ]; } } if (actions) { children.actions = maybeWrapContent(actions, { wrap: options.actionsWrapper, tag: options.actionsWrapperTag, class: options.actionsWrapperClass }); } } if (options.content) { return renderContent(core.evaluateFnOrValue(options.content, data, slotProps, children)); } if (children.slot) { return renderContent(children.slot); } const content = [ ...children.icon ? [ children.icon ] : [], ...children.text ? [ children.text ] : [], ...children.actions ? [ children.actions ] : [] ]; return renderContent(content); } function buildListBodyOptions(input) { const options = buildListBaseOptions(input, exports.Component.ListBody, { class: 'list-body', tag: 'ul' }); return { ...options, data: input.data || [], item: input.item }; } function buildListBody(input) { input = input || {}; const options = buildListBodyOptions(input); let slotProps; if (options.slotPropsBuilt) { slotProps = { data: vue.unref(options.data), ...options.slotProps }; } else { slotProps = { ...buildListBaseSlotProps(options), data: vue.unref(options.data), ...options.slotProps }; } if (core.hasNormalizedSlot(exports.SlotName.BODY, options.slotItems)) { return vue.h(options.tag, vue.mergeProps({ class: options.class }, options.props), core.normalizeSlot(exports.SlotName.BODY, slotProps, options.slotItems)); } // ---------------------------------------------------------------------- const items = vue.unref(options.data); if (items.length === 0) { return []; } return vue.h(options.tag, vue.mergeProps({ class: options.class }, options.props), items.map((item, index)=>buildListItem({ slotProps, slotPropsBuilt: true, slotItems: options.slotItems, ...options.item, data: item, index, busy: options.busy }))); } function buildListLoadingOptions(input) { const options = buildListBaseOptions(input, exports.Component.ListLoading, { class: 'list-loading' }); return { ...options }; } function buildListLoading(input) { input = input || {}; const options = buildListLoadingOptions(input); let slotProps; if (options.slotPropsBuilt) { slotProps = options.slotProps; } else { slotProps = { ...buildListBaseSlotProps(options), ...options.slotProps }; } if (!options.busy) { return []; } let content; if (core.hasNormalizedSlot(exports.SlotName.LOADING, options.slotItems)) { content = core.normalizeSlot(exports.SlotName.LOADING, slotProps, options.slotItems); } if (options.content) { if (typeof options.content === 'function') { content = [ options.content(slotProps) ]; } else { content = [ options.content ]; } } if (content) { return vue.h(options.tag, vue.mergeProps({ class: options.class }, options.props), [ content ]); } return []; } function buildListNoMoreOptions(input) { const options = buildListBaseOptions(input, exports.Component.ListNoMore, { class: 'list-no-more' }); const { buildOrFail } = core.createOptionBuilder(exports.Component.ListNoMore); return { ...options, content: buildOrFail({ key: 'content', value: input.content, alt: 'No more items available...' }) }; } function buildListNoMore(input) { input = input || {}; const options = buildListNoMoreOptions(input); const busy = vue.unref(options.busy); const total = vue.unref(options.total); if (busy) { return []; } if (typeof total === 'number') { if (total > 0) { return []; } } else if (core.isObject(options.meta) && core.hasOwnProperty(options.meta, 'total') && typeof options.meta.total === 'number' && options.meta.total > 0) { return []; } let slotProps; if (options.slotPropsBuilt) { slotProps = options.slotProps; } else { slotProps = { ...buildListBaseSlotProps(options), ...options.slotProps }; } const renderContent = (content)=>vue.h(options.tag, vue.mergeProps({ class: options.class }, options.props), [ content ]); if (core.hasNormalizedSlot(exports.SlotName.NO_MORE, options.slotItems)) { return renderContent(core.normalizeSlot(exports.SlotName.NO_MORE, slotProps, options.slotItems)); } if (typeof options.content === 'function') { return renderContent(options.content(slotProps)); } return renderContent(options.content); } function buildListOptions(input) { const options = buildListBaseOptions(input, exports.Component.List, { class: 'list' }); return { ...options, data: input.data ?? [], header: input.header ?? true, footer: input.footer ?? true, body: input.body ?? true, loading: input.loading ?? true, noMore: input.noMore ?? true }; } function buildList(input) { const options = buildListOptions(input); if (typeof options.total === 'undefined') { options.total = vue.unref(options.data).length; } const buildSlotProps = (props)=>({ ...props, ...buildListBaseSlotProps(options) }); const extendChildOptions = (input)=>{ input.slotItems = options.slotItems; input.slotProps = buildSlotProps(options.slotProps); input.slotPropsBuilt = true; input.busy = options.busy; input.meta = options.meta; input.total = options.total; return input; }; if (core.hasNormalizedSlot(exports.SlotName.DEFAULT, options.slotItems)) { const slotProps = { ...buildSlotProps(options.slotProps), data: vue.unref(options.data) }; return core.normalizeSlot(exports.SlotName.DEFAULT, slotProps, options.slotItems); } const children = []; if (options.header) { children.push(buildListHeader(extendChildOptions(boolableToObject(options.header)))); } if (options.body) { let childOptions; if (typeof options.body === 'boolean') { childOptions = { data: options.data, busy: options.busy }; } else { childOptions = options.body; childOptions.data = options.data; childOptions.busy = options.busy; } children.push(buildListBody(extendChildOptions(childOptions))); } if (options.loading) { children.push(buildListLoading(extendChildOptions(boolableToObject(options.loading)))); } if (options.noMore) { children.push(buildListNoMore(extendChildOptions(boolableToObject(options.noMore)))); } if (options.footer) { children.push(buildListFooter(extendChildOptions(boolableToObject(options.footer)))); } return vue.h(options.tag, vue.mergeProps({ class: options.class }, options.props), children); } function install(instance, options) { options ?? (options = {}); core.applyPluginBaseOptions(instance, options); } var index = { install }; exports.buildList = buildList; exports.buildListBaseOptions = buildListBaseOptions; exports.buildListBaseSlotProps = buildListBaseSlotProps; exports.buildListBody = buildListBody; exports.buildListBodyOptions = buildListBodyOptions; exports.buildListFooter = buildListFooter; exports.buildListFooterOptions = buildListFooterOptions; exports.buildListHeader = buildListHeader; exports.buildListHeaderOptions = buildListHeaderOptions; exports.buildListItem = buildListItem; exports.buildListItemOptions = buildListItemOptions; exports.buildListLoading = buildListLoading; exports.buildListLoadingOptions = buildListLoadingOptions; exports.buildListNoMore = buildListNoMore; exports.buildListNoMoreOptions = buildListNoMoreOptions; exports.buildListOptions = buildListOptions; exports.default = index; exports.install = install; //# sourceMappingURL=index.cjs.map