@dialpad/dialtone-vue
Version:
Vue component library for Dialpad's design system Dialtone
1 lines • 7.95 kB
Source Map (JSON)
{"version":3,"file":"image-viewer.cjs","sources":["../../../components/image_viewer/image_viewer.vue"],"sourcesContent":["<template>\n <div>\n <dt-button\n data-qa=\"dt-image-viewer-preview\"\n class=\"d-image-viewer__preview-button\"\n :aria-label=\"ariaLabel\"\n importance=\"clear\"\n @click=\"openModal\"\n >\n <img\n :class=\"imageButtonClass\"\n :src=\"imageSrc\"\n :alt=\"imageAlt\"\n >\n </dt-button>\n <portal\n v-if=\"isOpen\"\n :selector=\"appendTo\"\n >\n <div\n :aria-hidden=\"!isOpen ? 'true' : 'false'\"\n class=\"d-modal\"\n data-qa=\"dt-modal\"\n v-on=\"modalListeners\"\n @mouseover=\"showCloseButton = true\"\n @mouseleave=\"showCloseButton = false\"\n @focusin=\" showCloseButton = true\"\n @focusout=\" showCloseButton = false\"\n >\n <div\n data-qa=\"dt-image-viewer-full\"\n class=\"d-image-viewer__full\"\n role=\"dialog\"\n aria-modal=\"true\"\n >\n <img\n class=\"d-image-viewer__full__image\"\n :src=\"imageSrc\"\n :alt=\"imageAlt\"\n >\n </div>\n <transition name=\"fade\">\n <dt-button\n v-if=\"showCloseButton\"\n ref=\"closeImage\"\n data-qa=\"dt-image-viewer-close-btn\"\n class=\"d-modal__close\"\n circle\n size=\"lg\"\n importance=\"clear\"\n kind=\"inverted\"\n :aria-label=\"closeButtonTitle\"\n :title=\"closeButtonTitle\"\n @click=\"close\"\n >\n <template #icon>\n <dt-icon-close\n class=\"d-image-viewer__close-button\"\n size=\"400\"\n />\n </template>\n </dt-button>\n <sr-only-close-button\n v-else\n @close=\"close\"\n />\n </transition>\n </div>\n </portal>\n </div>\n</template>\n\n<script>\nimport Modal from '@/common/mixins/modal';\nimport { EVENT_KEYNAMES } from '@/common/constants';\nimport { DtIconClose } from '@dialpad/dialtone-icons/vue2';\nimport { DtButton } from '@/components/button';\nimport { Portal } from '@linusborg/vue-simple-portal';\nimport SrOnlyCloseButton from '@/common/sr_only_close_button.vue';\nimport { DialtoneLocalization } from '@/localization';\n\nexport default {\n name: 'DtImageViewer',\n\n components: {\n Portal,\n SrOnlyCloseButton,\n DtButton,\n DtIconClose,\n },\n\n mixins: [Modal],\n\n props: {\n /**\n * By default the portal appends to the body of the root parent. We can modify\n * this behaviour by passing an appendTo prop that points to an id or an html tag from the root of the parent.\n * The appendTo prop expects a CSS selector string or an actual DOM node.\n * type: string | HTMLElement, default: 'body'\n */\n appendTo: {\n type: String,\n default: 'body',\n },\n\n /**\n * Controls whether the image modal is shown. Leaving this null will have the image modal\n * trigger on click by default.\n * If you set this value, the default trigger behavior will be disabled and you can control it as you need.\n * Supports .sync modifier\n * @values null, true, false\n */\n open: {\n type: Boolean,\n default: null,\n },\n\n /**\n * URL of the image to be shown\n */\n imageSrc: {\n type: String,\n required: true,\n },\n\n /**\n * Alt text of image\n */\n imageAlt: {\n type: String,\n required: true,\n },\n\n /**\n * Image Class\n */\n imageButtonClass: {\n type: String,\n required: false,\n default: '',\n },\n\n /**\n * Aria label\n */\n ariaLabel: {\n type: String,\n required: true,\n },\n },\n\n emits: [\n /**\n * Emitted when popover is shown or hidden\n *\n * @event opened\n * @type {Boolean}\n */\n 'opened',\n\n /**\n * Event fired to sync the open prop with the parent component\n * @event update:open\n */\n 'update:open',\n ],\n\n data () {\n return {\n showCloseButton: true,\n isOpen: false,\n i18n: new DialtoneLocalization(),\n };\n },\n\n computed: {\n modalListeners () {\n return {\n ...this.$listeners,\n\n click: event => {\n (event.target === event.currentTarget) && this.close();\n },\n\n keydown: event => {\n switch (event.code) {\n case EVENT_KEYNAMES.esc:\n case EVENT_KEYNAMES.escape:\n this.close();\n break;\n case EVENT_KEYNAMES.tab:\n this.trapFocus(event);\n break;\n }\n },\n };\n },\n\n closeButtonTitle () {\n return this.i18n.$t('DIALTONE_CLOSE_BUTTON');\n },\n },\n\n watch: {\n isOpen: {\n immediate: true,\n handler (isShowing) {\n if (isShowing) {\n // Set a reference to the previously-active element, to which we'll return focus on modal close.\n this.previousActiveElement = document.activeElement;\n } else {\n // Modal is being hidden, so return focus to the previously active element before clearing the reference.\n this.previousActiveElement?.focus();\n this.previousActiveElement = null;\n }\n },\n },\n\n open: {\n handler: function (open) {\n if (open !== null) {\n this.isOpen = open;\n }\n },\n\n immediate: true,\n },\n },\n\n methods: {\n openModal () {\n // Has custom control passed in\n if (this.open !== null) {\n return;\n }\n this.isOpen = true;\n this.showCloseButton = true;\n this.$emit('opened', true);\n\n setTimeout(() => {\n this.focusAfterOpen();\n });\n },\n\n close () {\n this.isOpen = false;\n this.$emit('opened', false);\n\n if (this.open !== null) {\n this.$emit('update:open', false);\n }\n },\n\n focusAfterOpen () {\n this.$refs.closeImage?.$el.focus();\n },\n\n trapFocus (e) {\n if (this.isOpen) {\n this.focusTrappedTabPress(e);\n }\n },\n },\n};\n</script>\n"],"names":["_sfc_main","Portal","SrOnlyCloseButton","DtButton","DtIconClose","Modal","DialtoneLocalization","event","EVENT_KEYNAMES","isShowing","_a","open","e"],"mappings":"6eAiFAA,EAAA,CACA,KAAA,gBAEA,WAAA,CACA,OAAAC,EAAAA,OACA,kBAAAC,EAAAA,QACA,SAAAC,EAAAA,QACA,YAAAC,EAAAA,WACA,EAEA,OAAA,CAAAC,EAAAA,OAAA,EAEA,MAAA,CAOA,SAAA,CACA,KAAA,OACA,QAAA,MACA,EASA,KAAA,CACA,KAAA,QACA,QAAA,IACA,EAKA,SAAA,CACA,KAAA,OACA,SAAA,EACA,EAKA,SAAA,CACA,KAAA,OACA,SAAA,EACA,EAKA,iBAAA,CACA,KAAA,OACA,SAAA,GACA,QAAA,EACA,EAKA,UAAA,CACA,KAAA,OACA,SAAA,EACA,CACA,EAEA,MAAA,CAOA,SAMA,aACA,EAEA,MAAA,CACA,MAAA,CACA,gBAAA,GACA,OAAA,GACA,KAAA,IAAAC,EAAAA,oBACA,CACA,EAEA,SAAA,CACA,gBAAA,CACA,MAAA,CACA,GAAA,KAAA,WAEA,MAAAC,GAAA,CACAA,EAAA,SAAAA,EAAA,eAAA,KAAA,MAAA,CACA,EAEA,QAAAA,GAAA,CACA,OAAAA,EAAA,KAAA,CACA,KAAAC,EAAAA,eAAA,IACA,KAAAA,EAAAA,eAAA,OACA,KAAA,MAAA,EACA,MACA,KAAAA,EAAAA,eAAA,IACA,KAAA,UAAAD,CAAA,EACA,KACA,CACA,CACA,CACA,EAEA,kBAAA,CACA,OAAA,KAAA,KAAA,GAAA,uBAAA,CACA,CACA,EAEA,MAAA,CACA,OAAA,CACA,UAAA,GACA,QAAAE,EAAA,OACAA,EAEA,KAAA,sBAAA,SAAA,gBAGAC,EAAA,KAAA,wBAAA,MAAAA,EAAA,QACA,KAAA,sBAAA,KAEA,CACA,EAEA,KAAA,CACA,QAAA,SAAAC,EAAA,CACAA,IAAA,OACA,KAAA,OAAAA,EAEA,EAEA,UAAA,EACA,CACA,EAEA,QAAA,CACA,WAAA,CAEA,KAAA,OAAA,OAGA,KAAA,OAAA,GACA,KAAA,gBAAA,GACA,KAAA,MAAA,SAAA,EAAA,EAEA,WAAA,IAAA,CACA,KAAA,eAAA,CACA,CAAA,EACA,EAEA,OAAA,CACA,KAAA,OAAA,GACA,KAAA,MAAA,SAAA,EAAA,EAEA,KAAA,OAAA,MACA,KAAA,MAAA,cAAA,EAAA,CAEA,EAEA,gBAAA,QACAD,EAAA,KAAA,MAAA,aAAA,MAAAA,EAAA,IAAA,OACA,EAEA,UAAAE,EAAA,CACA,KAAA,QACA,KAAA,qBAAAA,CAAA,CAEA,CACA,CACA"}