-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The start of a WYSIWYG editor for Bootstrap 5.3 with vanilla JavaScript, no jQuery required!
- Loading branch information
Showing
5 changed files
with
589 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
<!DOCTYPE html> | ||
<html lang="en" data-bs-theme="dark"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Vanilla WYSIWYG Editor</title> | ||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> | ||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet"> | ||
</head> | ||
<body> | ||
<div class="container-fluid mt-5"> | ||
<div class="row-fluid"> | ||
<div class="col-lg-10 mx-auto"> | ||
<div class="card"> | ||
<div class="card-header"> | ||
<h2>Bootstrap 5.3.3 WYSIWYG, No JQuery</h2> | ||
</div> | ||
<ul id="toolbar" class="list-group list-group-flush"> | ||
<li class="list-group-item"> | ||
<div class="btn-toolbar justify-content-between"> | ||
<select id="headingSelect" class="form-select" style="width:auto;"> | ||
<option value="">Paragraph</option> | ||
<option value="h1">Heading 1</option> | ||
<option value="h2">Heading 2</option> | ||
<option value="h3">Heading 3</option> | ||
<option value="h4">Heading 4</option> | ||
<option value="h5">Heading 5</option> | ||
<option value="h6">Heading 6</option> | ||
</select> | ||
<select id="fontFamilySelect" class="form-select" style="width:auto;"> | ||
<option value="" disabled>Font Family</option> | ||
</select> | ||
<select id="fontSizeSelect" class="form-select" style="width:auto;"> | ||
<option value="" disabled>Font Size</option> | ||
</select> | ||
<button class="btn btn-outline-secondary" data-command="toggleSource" title="Toggle Source"><i class="bi bi-code-slash"></i></button> | ||
</div> | ||
</li> | ||
<li class="list-group-item"> | ||
<div class="btn-toolbar justify-content-between"> | ||
<div class="btn-group"> | ||
<button class="btn btn-outline-secondary" data-command="bold" title="Bold"><i class="bi bi-type-bold"></i></button> | ||
<button class="btn btn-outline-secondary" data-command="italic" title="Italic"><i class="bi bi-type-italic"></i></button> | ||
<button class="btn btn-outline-secondary" data-command="underline" title="Underline"><i class="bi bi-type-underline"></i></button> | ||
</div> | ||
<div class="btn-group"> | ||
<button class="btn btn-outline-secondary" data-command="justifyLeft" title="Align Left"><i class="bi bi-text-left"></i></button> | ||
<button class="btn btn-outline-secondary" data-command="justifyCenter" title="Align Center"><i class="bi bi-text-center"></i></button> | ||
<button class="btn btn-outline-secondary" data-command="justifyRight" title="Align Right"><i class="bi bi-text-right"></i></button> | ||
</div> | ||
<div class="btn-group"> | ||
<button class="btn btn-outline-secondary" data-command="insertUnorderedList" title="Bullet List"><i class="bi bi-list-ul"></i></button> | ||
<button class="btn btn-outline-secondary" data-command="insertOrderedList" title="Numbered List"><i class="bi bi-list-ol"></i></button> | ||
<button class="btn btn-outline-secondary" data-command="insertCircleList" title="Circle List"><i class="bi bi-record-circle"></i></button> | ||
<button class="btn btn-outline-secondary" data-command="insertSquareList" title="Square List"><i class="bi bi-square"></i></button> | ||
</div> | ||
</div> | ||
</li> | ||
<li class="list-group-item"> | ||
<div class="btn-toolbar justify-content-between"> | ||
<div class="btn-group"> | ||
<button class="btn btn-outline-secondary" data-command="createLink" title="Insert Link"><i class="bi bi-link"></i></button> | ||
<button class="btn btn-outline-secondary" data-command="insertImage" title="Insert Image"><i class="bi bi-image"></i></button> | ||
<button class="btn btn-outline-secondary" data-command="insertTable" title="Insert Table"><i class="bi bi-table"></i></button> | ||
</div> | ||
<div class="btn-group"> | ||
<button class="btn btn-outline-secondary bi bi-emoji-smile" data-command="insertEmoji" title="Insert Emoji"></button> | ||
<button class="btn btn-outline-secondary bi bi-hash" data-command="insertSymbol" title="Insert Symbol"></button> | ||
<button class="btn btn-outline-secondary bi bi-palette" data-command="insertColor" title="Text Color"></button> | ||
</div> | ||
<div class="btn-group"> | ||
<button class="btn btn-outline-secondary" data-command="undo" title="Undo"><i class="bi bi-arrow-counterclockwise"></i></button> | ||
<button class="btn btn-outline-secondary" data-command="redo" title="Redo"><i class="bi bi-arrow-clockwise"></i></button> | ||
</div> | ||
<div class="btn-group"> | ||
<button class="btn btn-outline-secondary" data-command="cut" title="Cut"><i class="bi bi-scissors"></i></button> | ||
<button class="btn btn-outline-secondary" data-command="copy" title="Copy"><i class="bi bi-files"></i></button> | ||
<button class="btn btn-outline-secondary" data-command="paste" title="Paste"><i class="bi bi-clipboard"></i></button> | ||
</div> | ||
</div> | ||
</li> | ||
</ul> | ||
<div class="card-body"> | ||
<div id="editor" class="form-control" contenteditable="true" style="min-height: 300px; max-height:700px; overflow-y: auto;"> | ||
Start typing here... | ||
</div> | ||
<textarea id="sourceView" class="form-control d-none" style="height: 300px; font-family: monospace;"></textarea> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
<script type="module" src="main.js"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
//import './style.css'; | ||
import { WysiwygEditor } from 'wysiwyg.js'; | ||
|
||
document.addEventListener('DOMContentLoaded', () => { | ||
const editor = new WysiwygEditor('#editor', { | ||
toolbar: '#toolbar' | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"name": "vanilla-wysiwyg", | ||
"private": true, | ||
"version": "0.0.0", | ||
"type": "module", | ||
"dependencies": { | ||
"bootstrap": "^5.3.3", | ||
"bootstrap-icons": "^1.11.3" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
#sourceView { | ||
font-family: 'Courier New', Courier, monospace; | ||
font-size: 14px; | ||
white-space: pre-wrap; | ||
resize: none; | ||
} | ||
|
||
/* Font controls */ | ||
#fontFamilySelect, | ||
#fontSizeSelect, | ||
#headingSelect { | ||
min-width: 120px; | ||
} | ||
|
||
#fontFamilySelect option { | ||
font-size: 14px; | ||
} | ||
|
||
/* Emoji and Symbol pickers */ | ||
.emoji-picker, | ||
.color-picker, | ||
.symbol-picker { | ||
position: absolute; | ||
background: var(--bs-body-bg); | ||
border: 1px solid var(--bs-border-color-translucent); | ||
border-radius: var(--bs-border-radius); | ||
padding: 5px; | ||
display: grid; | ||
grid-template-columns: repeat(5, 1fr); | ||
gap: 2px; | ||
z-index: 1000; | ||
box-shadow: var(--bs-box-shadow); | ||
} | ||
|
||
.emoji-picker button, | ||
.color-picker button, | ||
.symbol-picker button { | ||
background: none; | ||
border: 1px solid #464646; | ||
padding: 5px; | ||
cursor: pointer; | ||
font-size: 16px; | ||
} | ||
|
||
.emoji-picker button:hover, | ||
.color-picker button:hover, | ||
.symbol-picker button:hover { | ||
background: #575757; | ||
} | ||
|
||
/* Table styles */ | ||
.table { | ||
width: 100%; | ||
margin-bottom: 1rem; | ||
border-collapse: collapse; | ||
} | ||
|
||
.table th, | ||
.table td { | ||
padding: 0.75rem; | ||
vertical-align: top; | ||
border: 1px solid #dee2e6; | ||
min-width: 100px; | ||
} | ||
|
||
.table th { | ||
font-weight: bold; | ||
background-color: rgba(0, 0, 0, 0.05); | ||
} | ||
|
||
/* Add tooltips for better UX */ | ||
[data-command] { | ||
position: relative; | ||
} | ||
|
||
[data-command]::after { | ||
transition:opacity 1s linear; | ||
opacity:0; | ||
} | ||
[data-command]:hover::after { | ||
content: attr(title); | ||
position: absolute; | ||
bottom: 100%; | ||
left: 50%; | ||
transform: translateX(-50%); | ||
padding: 4px 8px; | ||
background-color: rgba(0, 0, 0, 0.8); | ||
color: white; | ||
opacity: 1; | ||
border-radius: 4px; | ||
font-size: 12px; | ||
white-space: nowrap; | ||
z-index: 1000; | ||
} |
Oops, something went wrong.