@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
231 lines (230 loc) • 6.48 kB
JavaScript
import g from "../../common/mixins/modal.js";
import { returnFirstEl as h } from "../../common/utils/index.js";
import { EVENT_KEYNAMES as a } from "../../common/constants/index.js";
import { DtIconClose as v } from "@dialpad/dialtone-icons/vue3";
import w from "../../shared/sr_only_close_button.js";
import { DialtoneLocalization as C } from "../../localization/index.js";
import { resolveComponent as u, createElementBlock as B, openBlock as l, createVNode as c, createBlock as m, createCommentVNode as b, withCtx as d, createElementVNode as n, normalizeClass as k, Teleport as O, mergeProps as T, toHandlers as y, Transition as E } from "vue";
import { _ as S } from "../../_plugin-vue_export-helper-CHgC5LLL.js";
import A from "../button/button.js";
const q = {
compatConfig: { MODE: 3 },
name: "DtImageViewer",
components: {
SrOnlyCloseButton: w,
DtButton: A,
DtIconClose: v
},
mixins: [g],
props: {
/**
* By default the portal appends to the body of the root parent. We can modify
* this behaviour by passing an appendTo prop that points to an id or an html tag from the root of the parent.
* The appendTo prop expects a CSS selector string or an actual DOM node.
* type: string | HTMLElement, default: 'body'
*/
appendTo: {
type: String,
default: "body"
},
/**
* Controls whether the image modal is shown. Leaving this null will have the image modal
* trigger on click by default.
* If you set this value, the default trigger behavior will be disabled and you can control it as you need.
* Supports .sync modifier
* @values null, true, false
*/
open: {
type: Boolean,
default: null
},
/**
* URL of the image to be shown
*/
imageSrc: {
type: String,
required: !0
},
/**
* Alt text of image
*/
imageAlt: {
type: String,
required: !0
},
/**
* Image Class
*/
imageButtonClass: {
type: String,
required: !1,
default: ""
},
/**
* Aria label
*/
ariaLabel: {
type: String,
required: !0
}
},
emits: [
/**
* Emitted when popover is shown or hidden
*
* @event opened
* @type {Boolean}
*/
"opened",
/**
* Event fired to sync the open prop with the parent component
* @event update:open
*/
"update:open"
],
data() {
return {
showCloseButton: !0,
isOpen: !1,
i18n: new C()
};
},
computed: {
modalListeners() {
return {
click: (e) => {
e.target === e.currentTarget && this.close();
},
keydown: (e) => {
switch (e.code) {
case a.esc:
case a.escape:
this.close();
break;
case a.tab:
this.trapFocus(e);
break;
}
}
};
},
closeButtonTitle() {
return this.i18n.$t("DIALTONE_CLOSE_BUTTON");
}
},
watch: {
isOpen: {
immediate: !0,
handler(e) {
var t;
e ? this.previousActiveElement = document.activeElement : ((t = this.previousActiveElement) == null || t.focus(), this.previousActiveElement = null);
}
},
open: {
handler: function(e) {
e !== null && (this.isOpen = e);
},
immediate: !0
}
},
methods: {
openModal() {
this.open === null && (this.isOpen = !0, this.showCloseButton = !0, this.$emit("opened", !0), setTimeout(() => {
this.focusAfterOpen();
}));
},
close() {
this.isOpen = !1, this.$emit("opened", !1), this.open !== null && this.$emit("update:open", !1);
},
focusAfterOpen() {
var e, t;
(t = h((e = this.$refs.closeImage) == null ? void 0 : e.$el)) == null || t.focus();
},
trapFocus(e) {
this.isOpen && this.focusTrappedTabPress(e);
}
}
}, D = ["src", "alt"], L = ["aria-hidden"], M = {
"data-qa": "dt-image-viewer-full",
class: "d-image-viewer__full",
role: "dialog",
"aria-modal": "true"
}, N = ["src", "alt"];
function I(e, t, o, V, i, s) {
const p = u("dt-button"), f = u("dt-icon-close"), _ = u("sr-only-close-button");
return l(), B("div", null, [
c(p, {
"data-qa": "dt-image-viewer-preview",
class: "d-image-viewer__preview-button",
"aria-label": o.ariaLabel,
importance: "clear",
onClick: s.openModal
}, {
default: d(() => [
n("img", {
class: k(o.imageButtonClass),
src: o.imageSrc,
alt: o.imageAlt
}, null, 10, D)
]),
_: 1
}, 8, ["aria-label", "onClick"]),
i.isOpen ? (l(), m(O, {
key: 0,
to: o.appendTo
}, [
n("div", T({
"aria-hidden": i.isOpen ? "false" : "true",
class: "d-modal",
"data-qa": "dt-modal"
}, y(s.modalListeners, !0), {
onMouseover: t[0] || (t[0] = (r) => i.showCloseButton = !0),
onMouseleave: t[1] || (t[1] = (r) => i.showCloseButton = !1),
onFocusin: t[2] || (t[2] = (r) => i.showCloseButton = !0),
onFocusout: t[3] || (t[3] = (r) => i.showCloseButton = !1)
}), [
n("div", M, [
n("img", {
class: "d-image-viewer__full__image",
src: o.imageSrc,
alt: o.imageAlt
}, null, 8, N)
]),
c(E, { name: "fade" }, {
default: d(() => [
i.showCloseButton ? (l(), m(p, {
key: 0,
ref: "closeImage",
"data-qa": "dt-image-viewer-close-btn",
class: "d-modal__close",
circle: "",
size: "lg",
importance: "clear",
kind: "inverted",
"aria-label": s.closeButtonTitle,
title: s.closeButtonTitle,
onClick: s.close
}, {
icon: d(() => [
c(f, {
class: "d-image-viewer__close-button",
size: "400"
})
]),
_: 1
}, 8, ["aria-label", "title", "onClick"])) : (l(), m(_, {
key: 1,
onClose: s.close
}, null, 8, ["onClose"]))
]),
_: 1
})
], 16, L)
], 8, ["to"])) : b("", !0)
]);
}
const G = /* @__PURE__ */ S(q, [["render", I]]);
export {
G as default
};
//# sourceMappingURL=image-viewer.js.map