JSFiddle - React, Tailwind, and code Playground
by levchenko_d
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/quill/1.1.10/quill.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/quill/1.1.10/quill.snow.min.css">
<script src="https://beat.today/javascripts/functions.js"></script>
<link rel="stylesheet" href="//cdn.quilljs.com/1.2.0/quill.bubble.css">
<div class="editor-wrapper">
<textarea name="task-description" style="display: none;"></textarea>
<form method="POST" action="/project/app/files/add" enctype="multipart/form-data" class="upload-form"><input type="file" name="files" multiple="multiple"></form>
<div class="toolbar ql-toolbar ql-snow">
<span class="ql-formats">
<button type="button" class="ql-bold"></button>
<button type="button" class="ql-italic">i</button>
<button type="button" class="ql-blockquote">"</button>
</span>
<span class="ql-formats">
<button type="button" class="ql-link">π</button>
<button type="button" class="ql-code-block"><\></button>
<button type="button" class="ql-list" value="bullet">π</button>
</span>
<span class="ql-formats">
<button type="button" class="ql-file">π</button>
<!-- <button type="button" class="ql-image">π</button> -->
<button type="button" class="ql-image-url" >π·</button>
<button type="button" class="ql-video">π₯</button>
</span>
</div>
<div class="editor ql-container ql-snow">
<p><strong>This is Hello World Example</strong></p>
<p> <a href="https://jsfiddle.net/levchenko_d/cnq51sxa/">Heey</a></p>
<p> www.google.com</p>
</div>
</div>
CSS
/* QL EDITOR */
.ql-toolbar.ql-snow,
.ql-container.ql-snow{
border: none;
}
.ql-toolbar.ql-snow{
display: inline-block;
box-shadow: 0 1px 3px rgba(0,0,0,0.15);
border-radius: 7px;
padding: 3px;
margin-left: 13px;
background: #fff;
}
.ql-toolbar .ql-file:after{
content: '';
}
.ql-snow .ql-tooltip {
background-color: rgba(0, 0, 0, 0.73);
border: none;
box-shadow: none;
color: #fff;
padding: 5px;
white-space: nowrap;
border-radius: 7px;
left: 10% !important;
right: 10%;
}
.ql-tooltip::before{
content: '' !important;
margin: 0;
}
.ql-snow .ql-tooltip .ql-action{
}
.ql-snow .ql-tooltip input[type=text] {
display: none;
border: none;
font-size: 13px;
height: 26px;
margin: 0;
padding: 3px 0;
width: calc(100% - 100px);
box-sizing: border-box;
background: transparent;
color: #fff;
}
.ql-snow .ql-tooltip input[type=text]:focus{
outline: none;
}
.ql-snow .ql-tooltip a.ql-preview{
max-width: calc(100% - 150px);
text-decoration: underline;
color: #fff;
}
.ql-tooltip-image.error{
background: red;
animation: shake 0.5s;
}
.ql-snow .ql-tooltip .ql-action, .ql-snow .ql-tooltip .ql-remove {
color: #fff;
float: right;
border: none;
max-width: 50px;
right: 20px;
}
.ql-snow .ql-tooltip a.ql-action::after{
border: none;
}
@keyframes shake {
10%, 90% {
transform: translate3d(-1px, 10px, 0);
}
20%, 80% {
transform: translate3d(2px, 10px, 0);
}
30%, 50%, 70% {
transform: translate3d(-4px, 10px, 0);
}
40%, 60% {
transform: translate3d(4px, 10px, 0);
}
}
.editor-wrapper{
}
.editor-wrapper .upload-form{
display: none;
}
.editor-wrapper .editor{
min-height: 200px;
padding: 15px;
}
.ql-editor{
padding: 0;
}
.editor p, .editor ol, .editor ul, .editor pre, .editor blockquote, .editor h1, .editor h2, .editor h3, .editor h4, .editor h5, .editor h6 {
margin: 0;
padding: 0;
...
JavaScript
App.q = function(selector){
return selector ? document.querySelector(selector) : {};
};
function removeClass(classNames){
var _t = this,
currentClass = _t.className;
classNames.split(' ').loop(function(className){
var reg = new RegExp('([^-_]|^)'+className+'([^-_]|$)', 'gm');
_t.className = currentClass.replace(reg, ' ').replace(/\s+/g, " ");
_t.className = _t.className.replace(/\s+/g, " ").trim();
});
return _t;
};
Element.prototype.removeClass = removeClass;
function parseIntSafe(n){ return parseInt(n)||0; };
App.create = function(tag, options){
var Elem = document.createElement(tag);
for(attr in options){
Elem.setAttribute(attr, options[attr]);
}
return Elem;
};
function isFn(fn){
if(fn && typeof(fn) === 'function'){
return fn
} else {
return function(){
return false
};
}
};
function getScrollTop(obj){
if(obj === document.body){
return document.documentElement.scrollTop || document.body.scrollTop;
} else {
return obj.scrollTop;
}
};
App.getScrollTop = function(obj){
if(obj === document.body){
return document.documentElement.scrollTop || document.body.scrollTop;
} else {
return obj.scrollTop;
}
};
/* Progress usage example:
<span class="progress-icon-wrapper">
<span class="text text-queue">
<!-- Progress queue will be placed here via innerText -->
</span>
<span class="icon-wrapper">
<!-- Progress icon will be placed here via appendChild -->
</span>
<span class="text loading-text">
<!-- Progress percentage (45%) will be placed here via innerText -->
</span>
</span>
var uploadProgress = new App.Progress({
wrapper : '.wrapper-selector',
progress : 49, //49%
//circular options
radius: 14, //default 14
strokeWidth:, 4 //default 4
});
uploadProgress.update(50);
uploadProgress.update(75);
// ...
// And so on
*/
var Progress = function(options){
var t = this,
o = options;
t.wrapperSelector = o.wrapper;
t.wrapper...