@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
301 lines (300 loc) • 9.23 kB
JavaScript
import { DEFAULT_FEED_ROW_STATE, FEED_ROW_STATE_BACKGROUND_COLOR } from "./feed_item_row_constants.js";
import Modal from "../../../common/mixins/modal.js";
import { DtIconUser } from "@dialpad/dialtone-icons/vue3";
import { resolveComponent, openBlock, createBlock, mergeProps, toHandlers, withCtx, createElementBlock, renderSlot, createVNode, createSlots, createCommentVNode, withDirectives, toDisplayString, vShow, createElementVNode } from "vue";
import _export_sfc from "../../../_virtual/_plugin-vue_export-helper.js";
import DtAvatar from "../../../components/avatar/avatar.vue.js";
import DtLazyShow from "../../../components/lazy_show/lazy_show.vue.js";
import DtListItem from "../../../components/list_item/list_item.vue.js";
import DtBadge from "../../../components/badge/badge.vue.js";
const _sfc_main = {
compatConfig: { MODE: 3 },
name: "DtRecipeFeedItemRow",
components: {
DtAvatar,
DtLazyShow,
DtListItem,
DtBadge,
DtIconUser
},
mixins: [Modal],
inheritAttrs: false,
props: {
/**
* Avatar seed, set this to the user's ID to get the same avatar background gradient each time it is displayed.
*/
avatarSeed: {
type: String,
default: null
},
/**
* Show avatar, show header text or dont show left time and vice versa
*/
showHeader: {
type: Boolean,
default: false
},
/**
* Optional avatar image url.
* If not provided it will use extracted initials from displayName.
*/
avatarImageUrl: {
type: String,
default: ""
},
/**
* The display name of the sender
*/
displayName: {
type: String,
default: ""
},
/**
* Initials will never be shown. Instead it will show a "User" icon.
*/
noInitials: {
type: Boolean,
default: false
},
/**
* time string displayed as is.
* Shown on the header when showHeader is true
*/
time: {
type: String,
default: ""
},
/**
* short time string without AM/PM displayed as is.
* Shown on the left of feed item when showHeader is false and isActive is true
*/
shortTime: {
type: String,
default: ""
},
/**
* A label displayed next to the displayName. Will not show if empty.
*/
labelText: {
type: String,
default: ""
},
/**
* displays a darkened background on the row.
*/
isActive: {
type: Boolean,
default: false
},
/**
* state for the feed item row. Can be normal, searched & error
*/
state: {
type: String,
default: DEFAULT_FEED_ROW_STATE,
validator: (state) => Object.keys(FEED_ROW_STATE_BACKGROUND_COLOR).includes(state)
}
},
emits: [
/**
* Fires when hovered over feed row
*
* @event hover
* @type {Boolean}
*/
"hover",
/**
* Fires when focused over feed row
*
* @event focus
* @type {Boolean}
*/
"focus",
/**
* Key down event
*
* @event keydown
* @type {KeyboardEvent}
*/
"keydown"
],
data() {
return {
transitionActive: false
};
},
computed: {
feedListeners() {
return {
mouseenter: () => this.setHover(true),
mouseleave: () => this.setHover(false),
focusin: () => this.setFocus(true),
focusout: () => this.setFocus(false),
transitionend: () => this.transitionComplete(),
keydown: (event) => {
switch (event.code) {
case "Tab":
this.trapFocus(event);
break;
}
this.$emit("keydown", event);
}
};
},
listItemClasses() {
return [
"d-recipe-feed-item-row",
{ "d-recipe-feed-item-row--active": this.isActive && this.state === DEFAULT_FEED_ROW_STATE },
{ "d-recipe-feed-item-row__state-transition": this.transitionActive },
FEED_ROW_STATE_BACKGROUND_COLOR[this.state]
];
}
},
watch: {
state: {
immediate: true,
handler: function(newState, oldState) {
if (newState !== DEFAULT_FEED_ROW_STATE) {
this.transitionActive = true;
}
}
}
},
methods: {
transitionComplete() {
if (this.state === DEFAULT_FEED_ROW_STATE) {
this.transitionActive = false;
}
},
trapFocus(e) {
this.focusTrappedTabPress(e);
},
setFocus(bool) {
this.$emit("focus", bool);
},
setHover(bool) {
this.$emit("hover", bool);
}
}
};
const _hoisted_1 = {
key: 0,
class: "d-recipe-feed-item-row__avatar-container"
};
const _hoisted_2 = { class: "d-recipe-feed-item-row__content" };
const _hoisted_3 = {
key: 0,
"data-qa": "dt-recipe-feed-item-row--header",
class: "d-recipe-feed-item-row__header"
};
const _hoisted_4 = { class: "d-recipe-feed-item-row__header-name" };
const _hoisted_5 = { class: "d-recipe-feed-item-row__header-time" };
const _hoisted_6 = { "data-qa": "dt-recipe-feed-item-row--content" };
const _hoisted_7 = {
key: 1,
"data-qa": "dt-recipe-feed-item-row--attachment",
class: "d-recipe-feed-item-row__attachment"
};
const _hoisted_8 = {
key: 0,
class: "d-recipe-feed-item-row__reactions",
"data-qa": "dt-recipe-feed-item-row--reactions"
};
const _hoisted_9 = {
key: 1,
class: "d-recipe-feed-item-row__threading"
};
const _hoisted_10 = {
"data-qa": "dt-recipe-feed-item-row--menu",
class: "d-recipe-feed-item-row__menu"
};
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_dt_icon_user = resolveComponent("dt-icon-user");
const _component_dt_avatar = resolveComponent("dt-avatar");
const _component_dt_badge = resolveComponent("dt-badge");
const _component_dt_lazy_show = resolveComponent("dt-lazy-show");
const _component_dt_list_item = resolveComponent("dt-list-item");
return openBlock(), createBlock(_component_dt_list_item, mergeProps({
ref: "FeedItemRef",
"navigation-type": "none"
}, _ctx.$attrs, {
class: $options.listItemClasses,
"data-qa": "dt-recipe-feed-item-row"
}, toHandlers($options.feedListeners)), {
left: withCtx(() => [
$props.showHeader ? (openBlock(), createElementBlock("div", _hoisted_1, [
renderSlot(_ctx.$slots, "avatar", {}, () => [
createVNode(_component_dt_avatar, {
"full-name": $props.displayName,
"image-src": $props.avatarImageUrl,
"image-alt": "",
seed: $props.avatarSeed
}, createSlots({ _: 2 }, [
$props.noInitials ? {
name: "icon",
fn: withCtx(({ iconSize }) => [
createVNode(_component_dt_icon_user, { size: iconSize }, null, 8, ["size"])
]),
key: "0"
} : void 0
]), 1032, ["full-name", "image-src", "seed"])
])
])) : createCommentVNode("", true),
!$props.showHeader ? withDirectives((openBlock(), createElementBlock("span", {
key: 1,
class: "d-recipe-feed-item-row__left-time",
"data-qa": "dt-recipe-feed-item-row--left-time"
}, toDisplayString($props.shortTime), 513)), [
[vShow, $props.isActive]
]) : createCommentVNode("", true)
]),
bottom: withCtx(() => [
_ctx.$slots.reactions ? (openBlock(), createElementBlock("div", _hoisted_8, [
renderSlot(_ctx.$slots, "reactions")
])) : createCommentVNode("", true),
_ctx.$slots.threading ? (openBlock(), createElementBlock("div", _hoisted_9, [
renderSlot(_ctx.$slots, "threading")
])) : createCommentVNode("", true),
withDirectives(createElementVNode("div", _hoisted_10, [
createVNode(_component_dt_lazy_show, {
appear: true,
transition: "fade",
show: $props.isActive
}, {
default: withCtx(() => [
renderSlot(_ctx.$slots, "menu")
]),
_: 3
}, 8, ["show"])
], 512), [
[vShow, $props.isActive]
])
]),
default: withCtx(() => [
createElementVNode("article", _hoisted_2, [
$props.showHeader ? (openBlock(), createElementBlock("div", _hoisted_3, [
renderSlot(_ctx.$slots, "displayName", {}, () => [
createElementVNode("p", _hoisted_4, toDisplayString($props.displayName), 1)
]),
createElementVNode("time", _hoisted_5, toDisplayString($props.time), 1),
$props.labelText ? (openBlock(), createBlock(_component_dt_badge, {
key: 0,
text: $props.labelText
}, null, 8, ["text"])) : createCommentVNode("", true)
])) : createCommentVNode("", true),
createElementVNode("span", _hoisted_6, [
renderSlot(_ctx.$slots, "default")
]),
_ctx.$slots.attachment ? (openBlock(), createElementBlock("div", _hoisted_7, [
renderSlot(_ctx.$slots, "attachment")
])) : createCommentVNode("", true)
])
]),
_: 3
}, 16, ["class"]);
}
const feed_item_row = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
export {
feed_item_row as default
};
//# sourceMappingURL=feed_item_row.vue.js.map