@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
219 lines (218 loc) • 6.4 kB
JavaScript
;
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