1<template> 2 <div class="input-password-toggle-container"> 3 <slot></slot> 4 <b-button 5 :title="togglePasswordLabel" 6 variant="link" 7 class="input-action-btn btn-icon-only" 8 :class="{ isVisible: isVisible }" 9 @click="toggleVisibility" 10 > 11 <icon-view-off v-if="isVisible" /> 12 <icon-view v-else /> 13 <span class="visually-hidden">{{ togglePasswordLabel }}</span> 14 </b-button> 15 </div> 16</template> 17 18<script> 19import IconView from '@carbon/icons-vue/es/view/20'; 20import IconViewOff from '@carbon/icons-vue/es/view--off/20'; 21import i18n from '@/i18n'; 22 23export default { 24 name: 'InputPasswordToggle', 25 components: { IconView, IconViewOff }, 26 data() { 27 return { 28 isVisible: false, 29 togglePasswordLabel: i18n.global.t('global.ariaLabel.showPassword'), 30 }; 31 }, 32 methods: { 33 toggleVisibility() { 34 const inputEl = this.$el.querySelector('input'); 35 36 this.isVisible = !this.isVisible; 37 38 if (inputEl && inputEl.nodeName === 'INPUT') { 39 inputEl.type = this.isVisible ? 'text' : 'password'; 40 } 41 42 this.isVisible 43 ? (this.togglePasswordLabel = i18n.global.t( 44 'global.ariaLabel.hidePassword', 45 )) 46 : (this.togglePasswordLabel = i18n.global.t( 47 'global.ariaLabel.showPassword', 48 )); 49 }, 50 }, 51}; 52</script> 53 54<style lang="scss" scoped> 55.input-password-toggle-container { 56 position: relative; 57 display: inline-block; 58} 59</style> 60