Add Zen mode to message compose body (#1489198) using the Idered/zen-form jQuery plugin
parent
6459944860
commit
29f7b272a5
Binary file not shown.
After Width: | Height: | Size: 294 B |
@ -0,0 +1,340 @@
|
||||
/* ================================== *\
|
||||
* Zen Form
|
||||
* ================================== */
|
||||
|
||||
.zen-forms {
|
||||
font: normal 18px/1.2 "Segoe UI", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif;
|
||||
position: fixed;
|
||||
z-index: 99999;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 20px 40px 20px 20px;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.zen-forms-body-wrap {
|
||||
width: 0;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.zen-forms-input-wrap {
|
||||
max-width: 800px;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
height: 90%;
|
||||
}
|
||||
|
||||
/**
|
||||
* Buttons style
|
||||
*/
|
||||
|
||||
.zen-forms-header {
|
||||
max-width: 800px;
|
||||
margin: 0 auto 16px auto;
|
||||
}
|
||||
|
||||
.zen-forms-header .zen-forms-subject {
|
||||
float: left;
|
||||
display: inline;
|
||||
margin: 0;
|
||||
color: #808080;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.zen-forms-close-button,
|
||||
.zen-forms-theme-switch {
|
||||
float: right;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
font-size: .8em;
|
||||
padding: 0 .5em;
|
||||
vertical-align: top;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
text-indent: -5000px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.zen-icon {
|
||||
background-image: url(images/zen-form-sprites.png);
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
position: absolute;
|
||||
zoom: 1;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
top: 1px;
|
||||
left: 1px;
|
||||
}
|
||||
|
||||
.zen-icon:before {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.light-theme .zen-forms-close-button:hover .zen-icon,
|
||||
.zen-icon--close {
|
||||
background-position: -16px 0;
|
||||
}
|
||||
|
||||
.light-theme .zen-forms-theme-switch:hover .zen-icon,
|
||||
.zen-icon--theme {
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
.light-theme .zen-icon--close,
|
||||
.zen-forms-close-button:hover .zen-icon {
|
||||
background-position: -16px -16px;
|
||||
}
|
||||
|
||||
.light-theme .zen-icon--theme,
|
||||
.zen-forms-theme-switch:hover .zen-icon {
|
||||
background-position: 0 -16px;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inputs basic style
|
||||
*/
|
||||
|
||||
.zen-forms-header:after,
|
||||
.zen-forms-input-wrap:after {
|
||||
clear: both;
|
||||
content: '';
|
||||
display: table;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.zen-forms .input {
|
||||
box-shadow: none;
|
||||
background: none;
|
||||
text-shadow: none;
|
||||
padding: 7px 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
.zen-forms .input:focus {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.zen-forms .select {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.zen-forms .custom-select-wrap + label {
|
||||
padding: 8px 3px;
|
||||
position: static;
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.zen-forms .custom-select-wrap {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.zen-forms .custom-select {
|
||||
border-radius: 5px;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
overflow: auto;
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
.zen-forms .custom-select a {
|
||||
display: inline-block;
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
padding: 6px 10px;
|
||||
display: none;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.zen-forms .custom-select span {
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.zen-forms .custom-select.is-open a,
|
||||
.zen-forms .custom-select .selected {
|
||||
position: static;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.zen-forms textarea {
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.zen-forms label {
|
||||
cursor: pointer;
|
||||
padding: 8px 8px 8px 0;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
font: inherit;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.zen-forms .input + label {
|
||||
position: absolute;
|
||||
display: none;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.zen-forms .empty + label {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.zen-forms .input:focus + label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
|
||||
.zen-forms .input:focus + label {
|
||||
display: block;
|
||||
background: #000;
|
||||
font-size: .8em;
|
||||
padding: 0 .5em;
|
||||
line-height: 2;
|
||||
border-radius: 3px;
|
||||
margin: 5px 15px 0 0;
|
||||
right: 100%;
|
||||
width: auto;
|
||||
white-space: nowrap;
|
||||
color: #fff;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.zen-forms .input:focus + label:after {
|
||||
content: '';
|
||||
top: 50%;
|
||||
left: 100%;
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
margin-top: -4px;
|
||||
position: absolute;
|
||||
border-style: solid;
|
||||
border-width: 4px 0 4px 4px;
|
||||
border-color: transparent transparent transparent #000000;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.zen-forms :focus {
|
||||
outline-color: transparent;
|
||||
outline-style: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dark theme
|
||||
*/
|
||||
.zen-forms {
|
||||
background: #151a1c;
|
||||
}
|
||||
|
||||
.zen-forms .zen-forms-close-button,
|
||||
.zen-forms .zen-forms-theme-switch {
|
||||
color: #768991;
|
||||
}
|
||||
|
||||
.zen-forms .zen-forms-close-button:hover,
|
||||
.zen-forms .zen-forms-theme-switch:hover {
|
||||
color: #707071;
|
||||
}
|
||||
|
||||
.zen-forms label {
|
||||
color: #415056;
|
||||
}
|
||||
|
||||
.zen-forms .input {
|
||||
color: #768991;
|
||||
}
|
||||
|
||||
.zen-forms .custom-select {
|
||||
background-color: #151a1c;
|
||||
border: 2px solid #0f1314;
|
||||
}
|
||||
|
||||
.zen-forms .custom-select a {
|
||||
color: #768991;
|
||||
}
|
||||
|
||||
.zen-forms .custom-select.is-open a:hover {
|
||||
background-color: #181e20;
|
||||
}
|
||||
|
||||
.zen-forms .custom-select.is-open .selected {
|
||||
background-color: #0f1314;
|
||||
}
|
||||
|
||||
/**
|
||||
* Light theme
|
||||
*/
|
||||
.zen-forms.light-theme {
|
||||
background: #fefefe;
|
||||
}
|
||||
|
||||
.zen-forms.light-theme .zen-forms-close-button,
|
||||
.zen-forms.light-theme .zen-forms-theme-switch {
|
||||
color: #707071;
|
||||
}
|
||||
|
||||
.zen-forms.light-theme .zen-forms-close-button:hover,
|
||||
.zen-forms.light-theme .zen-forms-theme-switch:hover {
|
||||
color: #768991;
|
||||
}
|
||||
|
||||
.zen-forms.light-theme label {
|
||||
color: #959697;
|
||||
}
|
||||
|
||||
.zen-forms.light-theme .input {
|
||||
color: #707071;
|
||||
}
|
||||
|
||||
.zen-forms.light-theme .custom-select {
|
||||
background-color: #fefefe;
|
||||
border: 2px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.zen-forms.light-theme .custom-select a {
|
||||
color: #707071;
|
||||
}
|
||||
|
||||
.zen-forms.light-theme .custom-select.is-open a:hover {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.zen-forms.light-theme .custom-select.is-open .selected {
|
||||
background-color: #e5e5e5;
|
||||
}
|
@ -0,0 +1,392 @@
|
||||
/** Zen Forms 1.0.3 | MIT License | git.io/zen-form */
|
||||
|
||||
(function ($) {
|
||||
|
||||
$.fn.zenForm = function (settings) {
|
||||
|
||||
settings = $.extend({
|
||||
trigger: '.go-zen',
|
||||
theme: 'dark'
|
||||
}, settings);
|
||||
|
||||
/**
|
||||
* Helper functions
|
||||
*/
|
||||
var Utils = {
|
||||
|
||||
/**
|
||||
* (Un)Wrap body content to hide overflow
|
||||
*/
|
||||
bodyWrap: function () {
|
||||
|
||||
var $body = $('body'),
|
||||
$wrap = $body.children('.zen-forms-body-wrap');
|
||||
|
||||
if ($wrap.length) {
|
||||
$wrap.children().unwrap();
|
||||
} else {
|
||||
$body.wrapInner('<div class="zen-forms-body-wrap"/>');
|
||||
}
|
||||
|
||||
}, // bodyWrap
|
||||
|
||||
/**
|
||||
* Watch inputs and add "empty" class if needed
|
||||
*/
|
||||
watchEmpty: function () {
|
||||
|
||||
App.Environment.find('input, textarea, select').each(function () {
|
||||
|
||||
$(this).on('change', function () {
|
||||
|
||||
$(this)[$(this).val() ? 'removeClass' : 'addClass']('empty');
|
||||
|
||||
}).trigger('change');
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Custom styled selects
|
||||
*/
|
||||
customSelect: function ($select, $customSelect) {
|
||||
|
||||
var $selected;
|
||||
|
||||
$customSelect.on('click', function (event) {
|
||||
|
||||
event.stopPropagation();
|
||||
|
||||
$selected = $customSelect.find('.selected');
|
||||
|
||||
$customSelect.toggleClass('is-open');
|
||||
|
||||
if ($customSelect.hasClass('is-open')) {
|
||||
$customSelect.scrollTop(
|
||||
$selected.position().top - $selected.outerHeight()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}).find('a').on('click', function () {
|
||||
|
||||
$(this).addClass('selected').siblings().removeClass('selected');
|
||||
|
||||
$select.val($(this).data('value'));
|
||||
|
||||
});
|
||||
|
||||
}, // customSelect
|
||||
|
||||
/**
|
||||
* Hide any elements(mostly selects) when clicked outside them
|
||||
*/
|
||||
manageSelects: function () {
|
||||
|
||||
$(document).on('click', function () {
|
||||
$('.is-open').removeClass('is-open');
|
||||
});
|
||||
|
||||
}, // manageSelects
|
||||
|
||||
/**
|
||||
* Hide any elements(mostly selects) when clicked outside them
|
||||
*/
|
||||
focusFirst: function () {
|
||||
|
||||
var $first = App.Environment.find('input').first();
|
||||
|
||||
// we need to re-set value to remove focus selection
|
||||
$first.focus().val($first.val());
|
||||
|
||||
} // focusFirst
|
||||
|
||||
}, // Utils
|
||||
|
||||
/**
|
||||
* Core functionality
|
||||
*/
|
||||
App = {
|
||||
|
||||
/**
|
||||
* Orginal form element
|
||||
*/
|
||||
Form: null,
|
||||
|
||||
/**
|
||||
* Wrapper element
|
||||
*/
|
||||
Environment: null,
|
||||
|
||||
/**
|
||||
* Functions to create and manipulate environment
|
||||
*/
|
||||
env: {
|
||||
|
||||
|
||||
/**
|
||||
* Object where elements created with App.env.addObject are appended
|
||||
*/
|
||||
wrapper: null,
|
||||
|
||||
create: function () {
|
||||
|
||||
// Callback: zf-initialize
|
||||
App.Form.trigger('zf-initialize');
|
||||
|
||||
Utils.bodyWrap();
|
||||
|
||||
App.Environment = $('<div>', {
|
||||
class: 'zen-forms' + (settings.theme == 'dark' ? '' : ' light-theme')
|
||||
}).hide().appendTo('body').fadeIn(200);
|
||||
|
||||
// ESC to exit. Thanks @ktmud
|
||||
$('body').on('keydown', function (event) {
|
||||
|
||||
if (event.which == 27)
|
||||
App.env.destroy($elements);
|
||||
|
||||
});
|
||||
|
||||
return App.Environment;
|
||||
|
||||
}, // create
|
||||
|
||||
/**
|
||||
* Update orginal inputs with new values and destroy Environment
|
||||
*/
|
||||
destroy: function ($elements) {
|
||||
|
||||
// Callback: zf-destroy
|
||||
App.Form.trigger('zf-destroy', App.Environment);
|
||||
|
||||
$('body').off('keydown');
|
||||
|
||||
// Update orginal inputs with new values
|
||||
$elements.each(function (i) {
|
||||
|
||||
var $el = $('#zen-forms-input' + i);
|
||||
|
||||
if ($el.length) {
|
||||
$(this).val($el.val());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Utils.bodyWrap();
|
||||
|
||||
// Hide and remove Environment
|
||||
App.Environment.fadeOut(200, function () {
|
||||
|
||||
App.env.wrapper = null;
|
||||
|
||||
App.Environment.remove();
|
||||
|
||||
});
|
||||
|
||||
// Callback: zf-destroyed
|
||||
App.Form.trigger('zf-destroyed');
|
||||
|
||||
}, // destroy
|
||||
|
||||
/**
|
||||
* Append inputs, textareas to Environment
|
||||
*/
|
||||
add: function ($elements) {
|
||||
|
||||
var $el, $label, value, id, ID, label;
|
||||
|
||||
$elements.each(function (i) {
|
||||
|
||||
App.env.wrapper = App.env.createObject('div', {
|
||||
class: 'zen-forms-input-wrap'
|
||||
}).appendTo(App.Environment);
|
||||
|
||||
$el = $(this);
|
||||
|
||||
value = $el.val();
|
||||
|
||||
id = $el.attr('id');
|
||||
|
||||
ID = 'zen-forms-input' + i;
|
||||
|
||||
label = $el.data('label') || $("label[for=" + id + "]").text() || $el.attr('placeholder') || '';
|
||||
|
||||
// Exclude specified elements
|
||||
if ($.inArray( $el.attr('type'), ['checkbox', 'radio', 'submit']) == -1) {
|
||||
|
||||
if ($el.is('input') )
|
||||
App.env.addInput($el, ID, value);
|
||||
else if ($el.is('select') )
|
||||
App.env.addSelect($el, ID);
|
||||
else
|
||||
App.env.addTextarea($el, ID, value);
|
||||
|
||||
$label = App.env.addObject('label', {
|
||||
for: ID,
|
||||
text: label
|
||||
});
|
||||
|
||||
if ($el.is('select') )
|
||||
$label.prependTo(App.env.wrapper);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Callback: zf-initialized
|
||||
App.Form.trigger('zf-initialized', App.Environment);
|
||||
|
||||
}, // add
|
||||
|
||||
addInput: function ($input, ID, value) {
|
||||
|
||||
return App.env.addObject('input', {
|
||||
id: ID,
|
||||
value: value,
|
||||
class: 'input',
|
||||
type: $input.attr('type')
|
||||
});
|
||||
|
||||
}, // addInput
|
||||
|
||||
addTextarea: function ($textarea, ID, value) {
|
||||
|
||||
return App.env.addObject('textarea', {
|
||||
id: ID,
|
||||
text: value,
|
||||
rows: 5,
|
||||
class: 'input'
|
||||
});
|
||||
|
||||
}, // addTextarea
|
||||
|
||||
addSelect: function ($orginalSelect, ID) {
|
||||
|
||||
var $select = App.env.addObject('select', {
|
||||
id: ID,
|
||||
class: 'select'
|
||||
}),
|
||||
$options = $orginalSelect.find('option'),
|
||||
$customSelect = App.env.addObject('div', {
|
||||
class: 'custom-select-wrap',
|
||||
html: '<div class="custom-select"></div>'
|
||||
}).children();
|
||||
|
||||
$select.append($options.clone());
|
||||
|
||||
$.each($options, function (i, option) {
|
||||
|
||||
App.env.createObject('a', {
|
||||
href: '#',
|
||||
html: '<span>' + $(option).text() + '</span>' ,
|
||||
'data-value': $(option).attr('value'),
|
||||
class: $(option).prop('selected') ? 'selected' : ''
|
||||
}).appendTo($customSelect);
|
||||
|
||||
});
|
||||
|
||||
$select.val($orginalSelect.val());
|
||||
|
||||
Utils.customSelect($select, $customSelect);
|
||||
|
||||
return $customSelect;
|
||||
|
||||
}, // addSelect
|
||||
|
||||
/**
|
||||
* Wrapper for creating jQuery objects
|
||||
*/
|
||||
createObject: function (type, params, fn, fnMethod) {
|
||||
|
||||
return $('<'+type+'>', params).on(fnMethod || 'click', fn);
|
||||
|
||||
}, // createObject
|
||||
|
||||
/**
|
||||
* Wrapper for adding jQuery objects to wrapper
|
||||
*/
|
||||
addObject: function (type, params, fn, fnMethod) {
|
||||
|
||||
return App.env.createObject(type, params, fn, fnMethod).appendTo(App.env.wrapper || App.Environment);
|
||||
|
||||
}, // addObject
|
||||
|
||||
switchTheme: function () {
|
||||
|
||||
App.Environment.toggleClass('light-theme');
|
||||
|
||||
} // switchTheme
|
||||
|
||||
}, // env
|
||||
|
||||
zen: function ($elements) {
|
||||
|
||||
// Create environment
|
||||
App.env.create();
|
||||
|
||||
// Add wrapper div for close and theme buttons
|
||||
App.env.wrapper = App.env.createObject('div', {
|
||||
class: 'zen-forms-header'
|
||||
}).appendTo(App.Environment);
|
||||
|
||||
// Add close button
|
||||
App.env.addObject('a', {
|
||||
class: 'zen-forms-close-button',
|
||||
html: '<i class="zen-icon zen-icon--close"></i> Exit Zen Mode'
|
||||
}, function () {
|
||||
App.env.destroy($elements);
|
||||
});
|
||||
|
||||
// Add theme switch button
|
||||
App.env.addObject('a', {
|
||||
class: 'zen-forms-theme-switch',
|
||||
html: '<i class="zen-icon zen-icon--theme"></i> Switch theme'
|
||||
}, function () {
|
||||
App.env.switchTheme();
|
||||
});
|
||||
|
||||
// Add inputs and textareas from form
|
||||
App.env.add($elements);
|
||||
|
||||
// Additional select functionality
|
||||
Utils.manageSelects();
|
||||
|
||||
// Select first input
|
||||
Utils.focusFirst();
|
||||
|
||||
// Add .empty class for empty inputs
|
||||
Utils.watchEmpty();
|
||||
|
||||
} // zen
|
||||
|
||||
}; // App
|
||||
|
||||
App.Form = $(this);
|
||||
|
||||
var $elements = App.Form.is('form') ? App.Form.find('input, textarea, select') : App.Form;
|
||||
|
||||
$(settings.trigger).on('click', function (event) {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
App.zen($elements);
|
||||
|
||||
});
|
||||
|
||||
// Command: destroy
|
||||
App.Form.on('destroy', function () {
|
||||
App.env.destroy($elements);
|
||||
});
|
||||
|
||||
// Command: init
|
||||
App.Form.on('init', function () {
|
||||
App.zen($elements);
|
||||
});
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
})(jQuery);
|
Loading…
Reference in New Issue