diff --git a/toast/css/toast-with-header.css b/toast/css/toast-with-header.css new file mode 100644 index 0000000..97bc142 --- /dev/null +++ b/toast/css/toast-with-header.css @@ -0,0 +1,62 @@ +.toast { + max-width: 350px; + overflow: hidden; + font-size: 0.875rem; + background-color: rgba(255, 255, 255, 0.5); + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.1); + border-radius: 0.25rem; + box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.1); + backdrop-filter: blur(10px); + display: none; +} + +.toast:not(:last-child) { + margin-bottom: 0.75rem; +} + +.toast_show { + display: block; +} + +.toast__header { + display: flex; + align-items: center; + padding: 0.25rem 2rem 0.25rem 0.75rem; + color: #212529; + background-color: rgba(255, 255, 255, 0.5); + background-clip: padding-box; + border-bottom: 1px solid rgba(0, 0, 0, 0.05); + position: relative; +} + +.toast__close { + position: absolute; + top: 0; + right: 10px; + padding: 0; + background-color: transparent; + border: 0; + cursor: pointer; + float: right; + font-size: 1.5rem; + font-weight: 700; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + opacity: 0.6; + appearance: button; + margin: 0; + font-family: inherit; + border-radius: 0; +} + +.toast__body { + padding: 0.75rem; +} + +input:not([type="checkbox"]) { + display: block; + font-size: 1rem; + margin-bottom: .5rem; +} \ No newline at end of file diff --git a/toast/css/toast.css b/toast/css/toast.css new file mode 100644 index 0000000..f219d38 --- /dev/null +++ b/toast/css/toast.css @@ -0,0 +1,51 @@ +.toast { + max-width: 350px; + overflow: hidden; + font-size: 0.875rem; + background-color: rgba(255, 255, 255, 0.5); + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.1); + border-radius: 0.25rem; + box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.1); + backdrop-filter: blur(10px); + display: none; + position: relative; + padding: 0.75rem 2rem 0.75rem 0.75rem; + overflow-wrap: break-word; + word-break: break-word; +} + +.toast:not(:last-child) { + margin-bottom: 0.75rem; +} + +.toast_show { + display: block; +} + +.toast__close { + position: absolute; + top: 0; + right: 10px; + padding: 0; + background-color: transparent; + border: 0; + cursor: pointer; + float: right; + font-size: 1.5rem; + font-weight: 700; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + opacity: 0.6; + appearance: button; + margin: 0; + font-family: inherit; + border-radius: 0; +} + +input:not([type="checkbox"]) { + display: block; + font-size: 1rem; + margin-bottom: .5rem; +} \ No newline at end of file diff --git a/toast/js/toast-with-header.js b/toast/js/toast-with-header.js new file mode 100644 index 0000000..bd4bb1b --- /dev/null +++ b/toast/js/toast-with-header.js @@ -0,0 +1,102 @@ +'use strict'; + +var Toast = function (element, config) { + var + _this = this, + _element = element, + _config = { + autohide: true, + delay: 5000 + }; + for (var prop in config) { + _config[prop] = config[prop]; + } + Object.defineProperty(this, 'element', { + get: function () { + return _element; + } + }); + Object.defineProperty(this, 'config', { + get: function () { + return _config; + } + }); + _element.addEventListener('click', function (e) { + if (e.target.classList.contains('toast__close')) { + _this.hide(); + } + }); +} + +Toast.prototype = { + show: function () { + var _this = this; + this.element.classList.add('toast_show'); + if (this.config.autohide) { + setTimeout(function () { + _this.hide(); + }, this.config.delay) + } + }, + hide: function () { + var event = new CustomEvent('hidden.toast', { detail: { toast: this.element } }); + this.element.classList.remove('toast_show'); + document.dispatchEvent(event); + } +}; + +Toast.create = function (header, body, color) { + var + fragment = document.createDocumentFragment(), + toast = document.createElement('div'), + toastHeader = document.createElement('div'), + toastClose = document.createElement('button'), + toastBody = document.createElement('div'); + toast.classList.add('toast'); + toast.style.backgroundColor = 'rgba(' + parseInt(color.substr(1, 2), 16) + ',' + parseInt(color.substr(3, 2), 16) + ',' + parseInt(color.substr(5, 2), 16) + ',0.5)'; + toastHeader.classList.add('toast__header'); + toastHeader.textContent = header; + toastClose.classList.add('toast__close'); + toastClose.setAttribute('type', 'button'); + toastClose.textContent = '×'; + toastBody.classList.add('toast__body'); + toastBody.textContent = body; + toastHeader.appendChild(toastClose); + toast.appendChild(toastHeader); + toast.appendChild(toastBody); + fragment.appendChild(toast); + return fragment; +}; + +Toast.add = function (params) { + var config = { + header: 'Название заголовка', + body: 'Текст сообщения...', + color: '#ffffff', + autohide: true, + delay: 5000 + }; + if (params !== undefined) { + for (var item in params) { + config[item] = params[item]; + } + } + if (!document.querySelector('.toasts')) { + var container = document.createElement('div'); + container.classList.add('toasts'); + container.style.cssText = 'position: fixed; top: 15px; right: 15px; width: 250px;'; + document.body.appendChild(container); + } + document.querySelector('.toasts').appendChild(Toast.create(config.header, config.body, config.color)); + var toasts = document.querySelectorAll('.toast'); + var toast = new Toast(toasts[toasts.length - 1], { autohide: config.autohide, delay: config.delay }); + toast.show(); + return toast; +} + +document.addEventListener('hidden.toast', function (e) { + var element = e.detail.toast; + if (element) { + element.parentNode.removeChild(element); + } +}); \ No newline at end of file diff --git a/toast/js/toast.js b/toast/js/toast.js new file mode 100644 index 0000000..02c3f25 --- /dev/null +++ b/toast/js/toast.js @@ -0,0 +1,95 @@ +'use strict'; + +var Toast = function (element, config) { + var + _this = this, + _element = element, + _config = { + autohide: true, + delay: 5000 + }; + for (var prop in config) { + _config[prop] = config[prop]; + } + Object.defineProperty(this, 'element', { + get: function () { + return _element; + } + }); + Object.defineProperty(this, 'config', { + get: function () { + return _config; + } + }); + _element.addEventListener('click', function (e) { + if (e.target.classList.contains('toast__close')) { + _this.hide(); + } + }); +} + +Toast.prototype = { + show: function () { + var _this = this; + this.element.classList.add('toast_show'); + if (this.config.autohide) { + setTimeout(function () { + _this.hide(); + }, this.config.delay) + } + }, + hide: function () { + var event = new CustomEvent('hidden.toast', { detail: { toast: this.element } }); + this.element.classList.remove('toast_show'); + document.dispatchEvent(event); + } +}; + +Toast.create = function (text, color) { + var + fragment = document.createDocumentFragment(), + toast = document.createElement('div'), + toastClose = document.createElement('button'); + toast.classList.add('toast'); + toast.style.backgroundColor = 'rgba(' + parseInt(color.substr(1, 2), 16) + ',' + parseInt(color.substr(3, 2), 16) + ',' + parseInt(color.substr(5, 2), 16) + ',0.5)'; + toast.textContent = text; + toastClose.classList.add('toast__close'); + toastClose.setAttribute('type', 'button'); + toastClose.textContent = '×'; + toast.appendChild(toastClose); + fragment.appendChild(toast); + return fragment; +}; + +Toast.add = function (params) { + var config = { + header: 'Название заголовка', + text: 'Текст сообщения...', + color: '#ffffff', + autohide: true, + delay: 5000 + }; + if (params !== undefined) { + for (var item in params) { + config[item] = params[item]; + } + } + if (!document.querySelector('.toasts')) { + var container = document.createElement('div'); + container.classList.add('toasts'); + container.style.cssText = 'position: fixed; top: 15px; right: 15px; width: 250px;'; + document.body.appendChild(container); + } + document.querySelector('.toasts').appendChild(Toast.create(config.text, config.color)); + var toasts = document.querySelectorAll('.toast'); + var toast = new Toast(toasts[toasts.length - 1], { autohide: config.autohide, delay: config.delay }); + toast.show(); + return toast; +} + +document.addEventListener('hidden.toast', function (e) { + var element = e.detail.toast; + if (element) { + element.parentNode.removeChild(element); + } +}); \ No newline at end of file