UNPKG

@dialpad/dialtone

Version:

Dialpad's Dialtone design system monorepo

219 lines (218 loc) 6.4 kB
"use strict"; Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } }); const list_item_constants = require("./list_item_constants.cjs"); const common_utils = require("../../common/utils.cjs"); const vue3 = require("@dialpad/dialtone-icons/vue3"); const vue = require("vue"); const _pluginVue_exportHelper = require("../../_virtual/_plugin-vue_export-helper.cjs"); const item_layout = require("../item_layout/item_layout.vue.cjs"); const ROLES = ["listitem", "menuitem", "option"]; const _sfc_main = { compatConfig: { MODE: 3 }, name: "DtListItem", components: { DtItemLayout: item_layout.default, DtIconCheck: vue3.DtIconCheck }, /** * Value provided from keyboard_list_navigation.js using id prop. */ inject: { highlightId: { default: null } }, props: { /** * Id for the item. */ id: { type: String, default() { return common_utils.default.getUniqueString(); } }, /** * String to use for the item's role. */ role: { type: String, default: "listitem", validator: (role) => ROLES.includes(role) }, /** * HTML element type (tag name) of the content wrapper element. */ elementType: { type: String, default: "li" }, /** * The type of child list item to use. * @values default, custom */ type: { type: String, default: list_item_constants.LIST_ITEM_TYPES.DEFAULT, validator: (t) => Object.values(list_item_constants.LIST_ITEM_TYPES).includes(t) }, /** * The type of navigation that this component should support. * - "arrow-keys" for items that are navigated with UP/DOWN keys. * - "tab" for items that are navigated using the TAB key. * - "none" for static items that are not interactive. * @values arrow-keys, tab, none */ navigationType: { type: String, default: list_item_constants.LIST_ITEM_NAVIGATION_TYPES.NONE, validator: (t) => Object.values(list_item_constants.LIST_ITEM_NAVIGATION_TYPES).includes(t) }, /** * Applies selected styles to the list item */ selected: { type: Boolean, default: false } }, emits: [ /** * Key down event * * @event keydown * @type {KeyboardEvent} */ "keydown", /** * Native mouse move event * * @event mousemove * @type {MouseEvent} */ "mousemove", /** * Native mouse leave event * * @event mouseleave * @type {MouseEvent} */ "mouseleave", /** * Mouse down event * * @event mousedown */ "mousedown" ], data() { return { injected: false, mouseHighlighted: false }; }, computed: { isDefaultType() { return this.type === list_item_constants.LIST_ITEM_TYPES.DEFAULT; }, listItemListeners() { return { keydown: (event) => { if (["enter", "space"].includes(event.code.toLowerCase())) { this.onClick(event); } this.$emit("keydown", event); }, mousemove: (event) => { this.onMouseHover(event); this.$emit("mousemove", event); }, mouseleave: (event) => { this.onMouseLeave(event); this.$emit("mouseleave", event); } }; }, /** * For keyboard navigation, whether this item is currently highlighted. * An injected highlightId will override the default mouseover highlight. */ isHighlighted() { if (this.isHoverable) { return this.highlightId && this.highlightId() ? this.id === this.highlightId() : this.mouseHighlighted; } return false; }, isFocusable() { return this.navigationType === list_item_constants.LIST_ITEM_NAVIGATION_TYPES.TAB; }, /** * Whether to apply hover styles. */ isHoverable() { return this.navigationType !== list_item_constants.LIST_ITEM_NAVIGATION_TYPES.NONE; } }, methods: { onClick(e) { this.$emit("click", e); }, onMouseHover() { this.mouseHighlighted = true; }, onMouseLeave() { this.mouseHighlighted = false; } } }; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _component_dt_icon_check = vue.resolveComponent("dt-icon-check"); const _component_dt_item_layout = vue.resolveComponent("dt-item-layout"); return vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent($props.elementType), vue.mergeProps({ id: $props.id, class: [ "d-list-item", { "d-list-item--focusable": $options.isFocusable, "d-list-item--highlighted": $options.isHighlighted, "d-list-item--static": !$options.isHoverable } ], tabindex: $options.isFocusable ? 0 : -1, role: $props.role, "aria-selected": $props.role === "listitem" ? void 0 : $options.isHighlighted }, vue.toHandlers($options.listItemListeners)), { default: vue.withCtx(() => [ $options.isDefaultType ? (vue.openBlock(), vue.createBlock(_component_dt_item_layout, { key: 0, unstyled: "", class: "d-list-item__wrapper", "left-class": "d-list-item__left", "content-class": "d-list-item__content", "title-class": "d-list-item__title", "subtitle-class": "d-list-item__subtitle", "bottom-class": "d-list-item__bottom", "right-class": "d-list-item__right", "selected-class": "d-list-item__selected" }, vue.createSlots({ _: 2 }, [ vue.renderList(_ctx.$slots, (_, slotName) => { return { name: slotName, fn: vue.withCtx(() => [ vue.renderSlot(_ctx.$slots, slotName) ]) }; }), $props.selected ? { name: "selected", fn: vue.withCtx(() => [ vue.createVNode(_component_dt_icon_check, { size: "400" }) ]), key: "0" } : void 0 ]), 1024)) : vue.renderSlot(_ctx.$slots, "default", { key: 1 }) ]), _: 3 }, 16, ["id", "class", "tabindex", "role", "aria-selected"]); } const DtListItem = /* @__PURE__ */ _pluginVue_exportHelper.default(_sfc_main, [["render", _sfc_render]]); exports.default = DtListItem; //# sourceMappingURL=list_item.vue.cjs.map