@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
276 lines (275 loc) • 7.82 kB
JavaScript
import utils from "../../common/utils.js";
import { TOAST_ROLES, TOAST_MIN_DURATION } from "./toast_constants.js";
import SrOnlyCloseButtonMixin from "../../common/mixins/sr_only_close_button.js";
import { resolveComponent, openBlock, createElementBlock, normalizeClass, createElementVNode, createBlock, withCtx, renderSlot, createCommentVNode, createVNode, createTextVNode, toDisplayString } from "vue";
import _export_sfc from "../../_virtual/_plugin-vue_export-helper.js";
import DtNoticeIcon from "../notice/notice_icon.vue.js";
import DtNoticeContent from "../notice/notice_content.vue.js";
import DtNoticeAction from "../notice/notice_action.vue.js";
import { NOTICE_KINDS } from "../notice/notice_constants.js";
const _sfc_main = {
compatConfig: { MODE: 3 },
name: "DtToast",
components: {
DtNoticeIcon,
DtNoticeContent,
DtNoticeAction
},
mixins: [SrOnlyCloseButtonMixin],
props: {
/**
* Sets an ID on the title element of the component. Useful for aria-describedby
* or aria-labelledby or any other reason you may need an id to refer to the title.
*/
titleId: {
type: String,
default() {
return utils.getUniqueString();
}
},
/**
* Sets an ID on the content element of the component. Useful for aria-describedby
* or aria-labelledby or any other reason you may need an id to refer to the content.
*/
contentId: {
type: String,
default() {
return utils.getUniqueString();
}
},
/**
* Title header of the toast. This can be left blank to remove the title from the toast entirely.
*/
title: {
type: String,
default: ""
},
/**
* Message of the toast. Overridden by default slot.
*/
message: {
type: String,
default: ""
},
/**
* Provides a role for the toast. 'status' is used by default to communicate a message. 'alert' is used to
* communicate an important message like an error that does not contain any interactive elements.
* @values status, alert
*/
role: {
type: String,
default: "status",
validator: (role) => {
return TOAST_ROLES.includes(role);
}
},
/**
* Severity level of the toast, sets the icon and background
* @values base, error, info, success, warning
*/
kind: {
type: String,
default: "base",
validator: (kind) => {
return NOTICE_KINDS.includes(kind);
}
},
/**
* Used in scenarios where the message needs to visually dominate the screen.
* @values true, false
*/
important: {
type: Boolean,
default: false
},
/**
* Controls whether the toast is shown. If a valid duration is provided, the toast will disappear
* after reaching the duration time, so it's convenient to use `v-model` with this prop to update
* the data in your component.
* Supports v-model
* @values true, false
*/
show: {
type: Boolean,
default: false
},
/**
* Props for the toast close button.
*/
closeButtonProps: {
type: Object,
default: () => ({})
},
/**
* Hides the close button from the toast
* @values true, false
*/
hideClose: {
type: Boolean,
default: false
},
/**
* Hides the icon from the notice
* @values true, false
*/
hideIcon: {
type: Boolean,
default: false
},
/**
* Hides the action from the notice
* @values true, false
*/
hideAction: {
type: Boolean,
default: false
},
/**
* The duration in ms the toast will display before disappearing.
* The toast won't disappear if the duration is not provided.
* If it's provided, it should be equal to or greater than 6000.
*/
duration: {
type: Number,
default: null,
validator: (duration) => {
return duration >= TOAST_MIN_DURATION;
}
}
},
emits: [
/**
* Close button click event
*
* @event close
*/
"close",
/**
* Native click event
*
* @event click
* @type {PointerEvent | KeyboardEvent}
*/
"click",
/**
* Sync show value
*
* @event update:show
*/
"update:show"
],
data() {
return {
isShown: false,
minDuration: TOAST_MIN_DURATION
};
},
computed: {
kindClass() {
const kindClasses = {
error: "d-toast--error",
info: "d-toast--info",
success: "d-toast--success",
warning: "d-toast--warning",
base: "d-toast--base"
};
return kindClasses[this.kind];
},
shouldSetTimeout() {
return !!this.duration && this.duration >= this.minDuration;
}
},
watch: {
show: {
handler: function(show) {
this.isShown = show;
if (show) {
this.setTimeout();
} else {
clearTimeout(this.displayTimer);
}
},
immediate: true
}
},
unmounted() {
clearTimeout(this.displayTimer);
},
methods: {
closeToast(event) {
this.$emit("update:show", false);
this.$emit("close", event);
},
setTimeout() {
if (this.shouldSetTimeout) {
this.displayTimer = setTimeout(() => {
this.isShown = false;
this.$emit("update:show", false);
}, this.duration);
}
}
}
};
const _hoisted_1 = ["aria-hidden"];
const _hoisted_2 = { class: "d-toast__dialog" };
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_dt_notice_icon = resolveComponent("dt-notice-icon");
const _component_dt_notice_content = resolveComponent("dt-notice-content");
const _component_dt_notice_action = resolveComponent("dt-notice-action");
return $data.isShown ? (openBlock(), createElementBlock("div", {
key: 0,
class: normalizeClass([
"d-toast",
$options.kindClass,
{ "d-toast--important": $props.important }
]),
"data-qa": "dt-toast",
"aria-hidden": (!$data.isShown).toString()
}, [
createElementVNode("div", _hoisted_2, [
!$props.hideIcon ? (openBlock(), createBlock(_component_dt_notice_icon, {
key: 0,
kind: $props.kind
}, {
default: withCtx(() => [
renderSlot(_ctx.$slots, "icon")
]),
_: 3
}, 8, ["kind"])) : createCommentVNode("", true),
createVNode(_component_dt_notice_content, {
"title-id": $props.titleId,
"content-id": $props.contentId,
title: $props.title,
role: $props.role
}, {
titleOverride: withCtx(() => [
renderSlot(_ctx.$slots, "titleOverride")
]),
default: withCtx(() => [
renderSlot(_ctx.$slots, "default", {}, () => [
createTextVNode(toDisplayString($props.message), 1)
])
]),
_: 3
}, 8, ["title-id", "content-id", "title", "role"]),
createVNode(_component_dt_notice_action, {
"hide-action": $props.hideAction,
"hide-close": $props.hideClose,
"close-button-props": $props.closeButtonProps,
"visually-hidden-close": _ctx.visuallyHiddenClose,
"visually-hidden-close-label": _ctx.visuallyHiddenCloseLabel,
onClose: $options.closeToast
}, {
default: withCtx(() => [
renderSlot(_ctx.$slots, "action")
]),
_: 3
}, 8, ["hide-action", "hide-close", "close-button-props", "visually-hidden-close", "visually-hidden-close-label", "onClose"])
])
], 10, _hoisted_1)) : createCommentVNode("", true);
}
const toast = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
export {
toast as default
};
//# sourceMappingURL=toast.vue.js.map