<h1 class="challenge-title">Hold</h1>
<h2 class="challenge-subtitle">#28ComponentsOfFebruaryDay3</h2>
<p class="challenge-part-of">Part of <a href="https://codepen.io/collection/DQRePJ" target="_blank">28 Components of February</a> collection.</p>

<div class="background"></div>
<div class="hold">
	<div class="start-note" contenteditable>Note...</div>
	<button class="btn btn-circle start-todo">
		<i class="far fa-check-square"></i>
	</button>
</div>
<div class="hold-note">
		<div class="hold-note__title" data-placeholder="Title" contenteditable></div>
		<div class="hold-note__note hidden" data-placeholder="Note..." contenteditable></div>
		<div class="hold-note__todo hidden">
			<div class="add-todo-item">
				<i class="fa fa-plus plus"></i> Add element
			</div>
		</div>
		<div class="hold-note__footer">
			<button class="btn close-keep">Close</button>
		</div>
	</div>
@import url("https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@100;400;700&display=swap");

$primary: #8661c1;
$default: #ced4da;

* {
	box-sizing: border-box;
}

html {
	font-size: 16px;
}

body {
	display: flex;
	padding: 0;
	margin: 0;
	align-items: center;
	flex-direction: column;
	min-height: 100vh;
	font-family: "Roboto Slab", serif;
	position: relative;
}
.background {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	min-height: 100%;
	background-color: #eeeef9;
	opacity: 0.3;
	background-image: repeating-radial-gradient(
			circle at 0 0,
			transparent 0,
			#eeeef9 20px
		),
		repeating-linear-gradient(#aa90d355, #aa90d3);
}

.challenge-title {
	text-align: center;
	padding: 0;
	margin: 1rem 0 0;
	color: $primary;
	font-size: 2rem;
	font-weight: bold;
}

.challenge-subtitle {
	text-align: center;
	margin: 0;
	font-size: 1.125rem;
	font-weight: normal;
	color: lighten($primary, 10%);
}

.challenge-part-of {
	text-align: center;
	margin: 1rem 0 0;
	font-size: 0.875rem;
	color: lighten($primary, 10%);
	position: fixed;
	bottom: 1rem;
	right: 1rem;
	z-index: 2;
	a,
	a:visited {
		color: lighten($primary, 10%);
		text-decoration-style: wavy;
		&:hover,
		&:active {
			color: lighten(lighten($primary, 10%), 10%);
		}
	}
}

div[contenteditable]:focus {
	outline: 0;
}

.btn {
	display: flex;
	align-items: center;
	background-color: transparent;
	border: 0;
	color: darken($default, 70%);
	padding: 0.5rem 1rem;
	font-size: 1rem;
	border-radius: 0.25rem;
	border: 1px solid transparent;
	transition: background-color 0.2s ease-in;
	cursor: pointer;
	&:hover {
		background-color: lighten($default, 13%);
	}
	&:active {
		background-color: darken($default, 5%);
	}
	&:focus {
		outline: 1px dotted darken($default, 20%);
	}
	&.btn-sm.btn-circle {
		width: 2rem;
		height: 2rem;
		font-size: 1rem;
	}
	&.btn-circle {
		border-radius: 50%;
		display: flex;
		align-items: center;
		justify-content: center;
		width: 2.5rem;
		height: 2.5rem;
		font-size: 1.25rem;
	}
}

.hidden {
	display: none;
}

.hold {
	border: 1px solid $default;
	width: 600px;
	max-width: 100%;
	height: 48px;
	margin: 2rem;
	border-radius: 0.5rem;
	padding: 0.5rem 1rem;
	display: flex;
	align-items: center;
	background-color: white;
	box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 15px -3px,
		rgba(0, 0, 0, 0.05) 0px 4px 6px -2px;
	.start-note {
		width: 200px;
		margin-right: auto;
	}
	position: relative;
	z-index: 2;
	&.hidden {
		display: none;
	}
}

.hold-note {
	box-shadow: rgba(0, 0, 0, 0.1) 0px 20px 25px -5px,
		rgba(0, 0, 0, 0.04) 0px 10px 10px -5px;
	width: 600px;
	max-width: 100%;
	min-height: 200px;
	margin: 2rem;
	border: 1px solid $default;
	background-color: white;
	position: relative;
	z-index: 2;
	border-radius: 0.5rem;
	pointer-events: none;
	display: none;
	flex-direction: column;
	&.open {
		pointer-events: initial;
		display: flex;
	}
	&__title {
		display: flex;
		padding: 0.875rem 1rem;
		min-height: 30px;
		align-items: center;
		word-break: break-all;
		&::before {
			top: 0.875rem;
		}
	}
	&__note {
		padding: 0.5rem 1rem;
		&::before {
			top: 0.5rem;
		}
	}
	&__title,
	&__note {
		position: relative;
		&::before {
			position: absolute;
			left: 1rem;
			content: attr(data-placeholder);
			color: darken($default, 10%);
		}
		&:focus,
		&.not-empty {
			&::before {
				display: none;
			}
		}
	}
	&__note,
	&__todo {
		flex: 1;
	}
	&__todo {
		.add-todo-item {
			cursor: pointer;
			color: darken($default, 20%);
			font-size: 0.875rem;
			position: relative;
			.plus {
				position: absolute;
				left: 2rem;
				top: 50%;
				transform: translateY(-50%);
			}
		}
		.todo-item,
		.add-todo-item {
			position: relative;
			padding: 0.5rem 0.5rem 0.5rem 3.5rem;
			border-top: 1px solid transparent;
			border-bottom: 1px solid transparent;
		}
		.todo-item {
			position: relative;
			display: flex;
			align-items: center;
			&:hover {
				.btn,
				.drag {
					visibility: visible;
				}
			}
			&-ghost {
				background-color: lighten($primary, 35%);
			}
			&.focus {
				border-color: $default;
			}
			.content {
				flex: 1 0 auto;
			}
			&.checked {
				.content {
					text-decoration: line-through;
				}
			}
			.btn {
				right: 1rem;
			}
			.btn,
			.drag,
			.check {
				position: absolute;
				top: 50%;
				transform: translateY(-50%);
			}
			.drag {
				left: 1rem;
				cursor: grab;
				&:active {
					cursor: grabbing;
				}
			}
			.check {
				left: 2rem;
				cursor: pointer;
			}
			.btn,
			.drag {
				visibility: hidden;
			}
		}
	}
	&__footer {
		margin: auto 0 0;
		display: flex;
		align-items: center;
		justify-content: flex-end;
		padding: 0.5rem 1rem;
	}
}
View Compiled
const createNote = document.querySelector(".start-note");
const createTodo = document.querySelector(".start-todo");
const closeKeep = document.querySelector(".close-keep");
const hold = document.querySelector(".hold");
const holdNote = document.querySelector(".hold-note");
const holdNoteTitle = document.querySelector('.hold-note__title');
const holdNoteNote = document.querySelector('.hold-note__note');
const holdNoteTodo = document.querySelector('.hold-note__todo');
const addTodoItem = document.querySelector('.add-todo-item');

function showHoldNote(type) {
	return function (e) {
		e.preventDefault();
		holdNote.classList.add("open");
		if(type === 'note'){
			hold.classList.add('hidden');
			holdNoteNote.classList.remove('hidden');
			holdNoteNote.focus();
			!holdNoteTodo.classList.contains('hidden') && holdNoteTodo.classList.add('hidden')
		} else {
			hold.classList.add('hidden');
			holdNoteTodo.classList.remove('hidden');
			!holdNoteNote.classList.contains('hidden') && holdNoteNote.classList.add('hidden')
		}
	};
}

createNote.addEventListener("click", showHoldNote('note'));
createTodo.addEventListener("click", showHoldNote('todo'));

function closeHoldNote(e) {
	e.preventDefault();
	hold.classList.remove("hidden");
	holdNote.classList.remove("open");
}

closeKeep.addEventListener('click', closeHoldNote);

function handlePlaceholder(e) {
	e.preventDefault();
	if(this.innerHTML.length > 0) {
		this.classList.add('not-empty');
	} else {
		this.classList.remove('not-empty')
	}
}

holdNoteTitle.addEventListener('focusout', handlePlaceholder);
holdNoteNote.addEventListener('focusout', handlePlaceholder);

holdNoteTodo.addEventListener('focusin', function(e) {
	if(e.target.classList.contains('content') && !e.target.parentNode.classList.contains('focus')){
		e.target.parentNode.classList.add('focus')
	}
});

holdNoteTodo.addEventListener('focusout', function(e) {
	if(e.target.classList.contains('content')){
		e.target.parentNode.classList.remove('focus')
	}
});

holdNoteTodo.addEventListener('click', function(e) {
	if(e.target.classList.contains('remove')){
		console.log(e.target)
		e.target.parentNode.remove()
	} else if (e.target.classList.contains('fa-times')) {
		e.target.parentNode.click()
	}
})

holdNoteTodo.addEventListener('click', function(e) {
	if(e.target.classList.contains('fa-square')){
		e.target.classList.remove('fa-square');
		e.target.classList.add('fa-check-square');
		e.target.parentNode.classList.add('checked');
	} else if (e.target.classList.contains('fa-check-square')) {
		e.target.classList.add('fa-square');
		e.target.classList.remove('fa-check-square');
		e.target.parentNode.classList.remove('checked');
	}
});

addTodoItem.addEventListener('click', function(e) {
	e.preventDefault();
	const todoItem = document.createElement('div');
	todoItem.classList.add('todo-item');
	todoItem.draggable = true;
	
	const content = document.createElement('div');
	content.classList.add('content');
	content.contentEditable = true;
	
	const drag = document.createElement('i');
	drag.classList.add('fa', 'fa-grip-vertical', 'drag');
	
	const check = document.createElement('i');
	check.classList.add('far', 'fa-square', 'check');
	
	const removeButton = document.createElement('button');
	removeButton.classList.add('btn', 'btn-sm', 'btn-circle', 'remove');
	
	const times = document.createElement('i');
	times.classList.add('fa', 'fa-times');

	removeButton.appendChild(times);
	
	todoItem.appendChild(content);
	todoItem.appendChild(drag);
	todoItem.appendChild(check);
	todoItem.appendChild(removeButton);
	
	holdNoteTodo.insertBefore(todoItem, this);
});

Sortable.create(holdNoteTodo, {
	handle: '.drag',
	draggable: '.todo-item',
	ghostClass: 'todo-item-ghost'
})
View Compiled

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.13.0/Sortable.min.js