All files / src/components/data-list DataList.ts

84% Statements 21/25
33.33% Branches 2/6
100% Functions 6/6
84% Lines 21/25

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 1152x 2x 2x   2x 2x 2x     2x       2x                 4x                                                             4x                   4x   4x   4x   4x                   4x   4x   4x                                   4x   4x   4x                 2x
import CustomElement from "../../custom-element/CustomElement";
import getStyle from "../../custom-element/helpers/css/style/getStyle";
import defineCustomElement from "../../custom-element/helpers/defineCustomElement";
import { CustomElementPropertyMetadata } from "../../custom-element/interfaces";
import SelectionContainerMixin from "../../custom-element/mixins/components/selection-container/SelectionContainerMixin";
import DataHolderMixin from "../../custom-element/mixins/data/DataHolderMixin";
import html from "../../renderer/html";
import { NodePatchingData } from "../../renderer/NodePatcher";
 
const defaultItemStyle = `
    list-style-type: none;
`;
 
export default class DataList extends
    SelectionContainerMixin(
        DataHolderMixin(
            CustomElement
        )
    ) {
 
    static get properties(): Record<string, CustomElementPropertyMetadata> {
 
        return {
 
            /**
             * The name of the field to extract the value to display on each item
             */
            displayField: {
                attribute: 'display-field',
                type: String
            },
 
            /**
             * The style of each list item
             */
            itemStyle: {
                attribute: 'item-style',
                type: [String, Object, Function]
            },
 
            /**
             * The template to render the item
             */
            itemTemplate: {
                attribute: 'item-template',
                type: Function,
                defer: true // Store the function itself instead of executing it to get its return value when initializing the property
            }
        };
    }
 
    render(): NodePatchingData {
 
        return html`<ul>
            ${this.renderItems()}
        </ul>`;
    }
 
    renderItems(): NodePatchingData {
 
        const {
            data,
            idField
        } = this;
 
        return data.map(record => {
 
            const id = record[idField];
 
            return html`<li key=${id} style=${this.getItemStyle()}>
                <gcl-selectable selectable=${this.selectable} select-value=${record}>${this.renderItem(record)}</gcl-selectable>
            </li>`;
        });
    }
 
    getItemStyle(): string {
 
        const {
            itemStyle
        } = this;
 
        Eif (itemStyle === undefined) {
 
            return defaultItemStyle;
        }
 
        if (typeof itemStyle === 'string') {
 
            return `${defaultItemStyle} ${itemStyle}`;
        }
        else { // Assume it is an object
 
            return `${defaultItemStyle} ${getStyle(itemStyle)}`;
        }
    }
 
    renderItem(record: Record<string, any>): NodePatchingData {
 
        const {
            displayField,
            itemTemplate
        } = this;
 
        Eif (itemTemplate === undefined) {
 
            return html`${record[displayField]}`;
        }
        else {
 
            return itemTemplate(record);
        }
    }
}
 
defineCustomElement('gcl-data-list', DataList);