Commit 1811c08a authored by Fatih Acet's avatar Fatih Acet Committed by Paul Slaughter

Make flash banners dismissable with x button

if you click anywhere of the Flash banner,
it will be dismissed. This UX improvement
changes the default behavior. Flash banners
will only be dismissable with by clicking
the x button. This will also fix the UX issue
around trying to c/p error messages.
parent 7082bf05
...@@ -40,13 +40,17 @@ const createFlashEl = (message, type) => ` ...@@ -40,13 +40,17 @@ const createFlashEl = (message, type) => `
<div class="flash-content flash-${type} rounded"> <div class="flash-content flash-${type} rounded">
<div class="flash-text"> <div class="flash-text">
${_.escape(message)} ${_.escape(message)}
<div class="close-icon-wrapper js-close-icon">
${spriteIcon('close', 'close-icon')} ${spriteIcon('close', 'close-icon')}
</div> </div>
</div> </div>
</div>
`; `;
const removeFlashClickListener = (flashEl, fadeTransition) => { const removeFlashClickListener = (flashEl, fadeTransition) => {
flashEl.addEventListener('click', () => hideFlash(flashEl, fadeTransition)); flashEl
.querySelector('.js-close-icon')
.addEventListener('click', () => hideFlash(flashEl, fadeTransition));
}; };
/* /*
...@@ -78,7 +82,6 @@ const createFlash = function createFlash( ...@@ -78,7 +82,6 @@ const createFlash = function createFlash(
flashContainer.innerHTML = createFlashEl(message, type); flashContainer.innerHTML = createFlashEl(message, type);
const flashEl = flashContainer.querySelector(`.flash-${type}`); const flashEl = flashContainer.querySelector(`.flash-${type}`);
removeFlashClickListener(flashEl, fadeTransition);
if (actionConfig) { if (actionConfig) {
flashEl.innerHTML += createAction(actionConfig); flashEl.innerHTML += createAction(actionConfig);
...@@ -90,6 +93,8 @@ const createFlash = function createFlash( ...@@ -90,6 +93,8 @@ const createFlash = function createFlash(
} }
} }
removeFlashClickListener(flashEl, fadeTransition);
flashContainer.style.display = 'block'; flashContainer.style.display = 'block';
if (addBodyClass) document.body.classList.add('flash-shown'); if (addBodyClass) document.body.classList.add('flash-shown');
......
$notification-box-shadow-color: rgba(0, 0, 0, 0.25); $notification-box-shadow-color: rgba(0, 0, 0, 0.25);
.flash-container { .flash-container {
cursor: pointer;
margin: 0; margin: 0;
margin-bottom: $gl-padding; margin-bottom: $gl-padding;
font-size: 14px; font-size: 14px;
...@@ -19,12 +18,17 @@ $notification-box-shadow-color: rgba(0, 0, 0, 0.25); ...@@ -19,12 +18,17 @@ $notification-box-shadow-color: rgba(0, 0, 0, 0.25);
} }
} }
.close-icon-wrapper {
padding: ($gl-btn-padding + $gl-padding-4) $gl-padding $gl-btn-padding;
position: absolute;
right: 0;
top: 0;
cursor: pointer;
.close-icon { .close-icon {
width: 16px; width: 16px;
height: 16px; height: 16px;
position: absolute; }
right: $gl-padding;
top: $gl-padding;
} }
.flash-notice, .flash-notice,
......
...@@ -5,4 +5,5 @@ ...@@ -5,4 +5,5 @@
- if value - if value
%div{ class: "flash-content flash-#{key} rounded" } %div{ class: "flash-content flash-#{key} rounded" }
%span= value %span= value
%div{ class: "close-icon-wrapper js-close-icon" }
= sprite_icon('close', size: 16, css_class: 'close-icon') = sprite_icon('close', size: 16, css_class: 'close-icon')
---
title: Banners should only be dismissable by clicking x button
merge_request: 17642
author:
type: changed
...@@ -176,7 +176,7 @@ describe('Flash', () => { ...@@ -176,7 +176,7 @@ describe('Flash', () => {
it('removes element after clicking', () => { it('removes element after clicking', () => {
flash('test', 'alert', document, null, false, true); flash('test', 'alert', document, null, false, true);
document.querySelector('.flash-alert').click(); document.querySelector('.flash-alert .js-close-icon').click();
expect(document.querySelector('.flash-alert')).toBeNull(); expect(document.querySelector('.flash-alert')).toBeNull();
...@@ -210,7 +210,13 @@ describe('Flash', () => { ...@@ -210,7 +210,13 @@ describe('Flash', () => {
describe('removeFlashClickListener', () => { describe('removeFlashClickListener', () => {
beforeEach(() => { beforeEach(() => {
document.body.innerHTML += '<div class="flash-container"><div class="flash"></div></div>'; document.body.innerHTML += `
<div class="flash-container">
<div class="flash">
<div class="close-icon js-close-icon"></div>
</div>
</div>
`;
}); });
it('removes global flash on click', done => { it('removes global flash on click', done => {
...@@ -218,7 +224,7 @@ describe('Flash', () => { ...@@ -218,7 +224,7 @@ describe('Flash', () => {
removeFlashClickListener(flashEl, false); removeFlashClickListener(flashEl, false);
flashEl.click(); flashEl.querySelector('.js-close-icon').click();
setTimeout(() => { setTimeout(() => {
expect(document.querySelector('.flash')).toBeNull(); expect(document.querySelector('.flash')).toBeNull();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment