UNPKG

@dialpad/dialtone

Version:

Dialpad's Dialtone design system monorepo

192 lines (191 loc) 5.84 kB
import Modal from "../../common/mixins/modal.js"; import { EVENT_KEYNAMES } from "../../common/constants.js"; import { DtIconClose } from "@dialpad/dialtone-icons/vue2"; import { Portal } from "@linusborg/vue-simple-portal"; import normalizeComponent from "../../_virtual/_plugin-vue2_normalizer.js"; import DtButton from "../button/button.vue.js"; const _sfc_main = { name: "DtImageViewer", components: { Portal, DtButton, DtIconClose }, mixins: [Modal], 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: true }, /** * Alt text of image */ imageAlt: { type: String, required: true }, /** * Image Class */ imageButtonClass: { type: String, required: false, default: "" }, /** * Aria label */ ariaLabel: { type: String, required: true }, /** * Aria label for close button */ closeAriaLabel: { type: String, required: true } }, 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: true, isOpen: false }; }, computed: { modalListeners() { return { ...this.$listeners, click: (event) => { event.target === event.currentTarget && this.close(); }, keydown: (event) => { switch (event.code) { case EVENT_KEYNAMES.esc: case EVENT_KEYNAMES.escape: this.close(); break; case EVENT_KEYNAMES.tab: this.trapFocus(event); break; } } }; } }, watch: { isOpen: { immediate: true, handler(isShowing) { var _a; if (isShowing) { this.previousActiveElement = document.activeElement; } else { (_a = this.previousActiveElement) == null ? void 0 : _a.focus(); this.previousActiveElement = null; } } }, open: { handler: function(open) { if (open !== null) { this.isOpen = open; } }, immediate: true } }, methods: { openModal() { if (this.open !== null) { return; } this.isOpen = true; this.showCloseButton = true; this.$emit("opened", true); setTimeout(() => { this.focusAfterOpen(); }); }, close() { this.isOpen = false; this.$emit("opened", false); if (this.open !== null) { this.$emit("update:open", false); } }, focusAfterOpen() { var _a; (_a = this.$refs.closeImage) == null ? void 0 : _a.$el.focus(); }, trapFocus(e) { if (this.isOpen) { this.focusTrappedTabPress(e); } } } }; var _sfc_render = function render() { var _vm = this, _c = _vm._self._c; return _c("div", [_c("dt-button", { staticClass: "d-image-viewer__preview-button", attrs: { "data-qa": "dt-image-viewer-preview", "aria-label": _vm.ariaLabel, "importance": "clear" }, on: { "click": _vm.openModal } }, [_c("img", { class: _vm.imageButtonClass, attrs: { "src": _vm.imageSrc, "alt": _vm.imageAlt } })]), _vm.isOpen ? _c("portal", { attrs: { "selector": _vm.appendTo } }, [_c("div", _vm._g({ staticClass: "d-modal", attrs: { "aria-hidden": !_vm.isOpen ? "true" : "false", "data-qa": "dt-modal" }, on: { "mouseover": function($event) { _vm.showCloseButton = true; }, "mouseleave": function($event) { _vm.showCloseButton = false; }, "focusin": function($event) { _vm.showCloseButton = true; }, "focusout": function($event) { _vm.showCloseButton = false; } } }, _vm.modalListeners), [_c("div", { staticClass: "d-image-viewer__full", attrs: { "data-qa": "dt-image-viewer-full", "role": "dialog", "aria-modal": "true" } }, [_c("img", { staticClass: "d-image-viewer__full__image", attrs: { "src": _vm.imageSrc, "alt": _vm.imageAlt } })]), _c("transition", { attrs: { "name": "fade" } }, [_vm.showCloseButton ? _c("dt-button", { ref: "closeImage", staticClass: "d-modal__close", attrs: { "data-qa": "dt-image-viewer-close-btn", "circle": "", "size": "lg", "importance": "clear", "kind": "inverted", "aria-label": _vm.closeAriaLabel }, on: { "click": _vm.close }, scopedSlots: _vm._u([{ key: "icon", fn: function() { return [_c("dt-icon-close", { staticClass: "d-image-viewer__close-button", attrs: { "size": "400" } })]; }, proxy: true }], null, false, 3317018023) }) : _vm._e()], 1)], 1)]) : _vm._e()], 1); }; var _sfc_staticRenderFns = []; var __component__ = /* @__PURE__ */ normalizeComponent( _sfc_main, _sfc_render, _sfc_staticRenderFns ); const DtImageViewer = __component__.exports; export { DtImageViewer as default }; //# sourceMappingURL=image_viewer.vue.js.map