Kaynağa Gözat

fix(Checkboxes): more modern style of checkbox for AddToPlaylist and Preferences toggles

Signed-off-by: Jonathan <theflametrooper@gmail.com>
Jonathan 3 yıl önce
ebeveyn
işleme
4b8459f92c

+ 48 - 46
frontend/src/App.vue

@@ -396,10 +396,6 @@ a {
 					p {
 						color: var(--white);
 					}
-
-					.checkbox-control label span {
-						background-color: var(--dark-grey-2);
-					}
 				}
 			}
 		}
@@ -537,7 +533,7 @@ a {
 	&.songActions-theme,
 	&.addToPlaylist-theme {
 		.tippy-arrow {
-			border-top-color: var(--light-grey-3);
+			border-top-color: var(--white);
 		}
 	}
 	&.confirm-theme .tippy-arrow {
@@ -548,7 +544,7 @@ a {
 	&.songActions-theme,
 	&.addToPlaylist-theme {
 		.tippy-arrow {
-			border-bottom-color: var(--light-grey-3);
+			border-bottom-color: var(--white);
 		}
 	}
 	&.confirm-theme .tippy-arrow {
@@ -559,7 +555,7 @@ a {
 	&.songActions-theme,
 	&.addToPlaylist-theme {
 		.tippy-arrow {
-			border-left-color: var(--light-grey-3);
+			border-left-color: var(--white);
 		}
 	}
 	&.confirm-theme .tippy-arrow {
@@ -570,7 +566,7 @@ a {
 	&.songActions-theme,
 	&.addToPlaylist-theme {
 		.tippy-arrow {
-			border-right-color: var(--light-grey-3);
+			border-right-color: var(--white);
 		}
 	}
 	&.confirm-theme .tippy-arrow {
@@ -600,55 +596,61 @@ a {
 
 			.checkbox-control {
 				display: flex;
+				flex-direction: row;
 				align-items: center;
-				margin-bottom: 0 !important;
-				width: inherit;
 
-				input {
-					margin-right: 5px;
+				p {
+					margin-left: 10px;
 				}
 
-				input[type="checkbox"] {
-					opacity: 0;
-					position: absolute;
+				.switch {
+					position: relative;
+					display: inline-block;
+					flex-shrink: 0;
+					width: 40px;
+					height: 24px;
 				}
 
-				label {
-					display: flex;
-					flex-direction: row;
-					align-items: center;
-					width: inherit;
-
-					span {
-						cursor: pointer;
-						min-width: 24px;
-						height: 24px;
-						background-color: var(--white);
-						display: inline-block;
-						border: 1px solid var(--dark-grey-2);
-						position: relative;
-						border-radius: 3px;
-					}
+				.switch input {
+					opacity: 0;
+					width: 0;
+					height: 0;
+				}
 
-					p {
-						margin-left: 10px;
-						cursor: pointer;
-						color: var(--black);
-						overflow: hidden;
-						text-overflow: ellipsis;
-						white-space: nowrap;
-					}
+				.slider {
+					position: absolute;
+					cursor: pointer;
+					top: 0;
+					left: 0;
+					right: 0;
+					bottom: 0;
+					background-color: #ccc;
+					transition: 0.2s;
+					border-radius: 34px;
 				}
 
-				input[type="checkbox"]:checked + label span::after {
+				.slider:before {
+					position: absolute;
 					content: "";
-					width: 18px;
-					height: 18px;
-					left: 2px;
-					top: 2px;
-					border-radius: 3px;
+					height: 16px;
+					width: 16px;
+					left: 4px;
+					bottom: 4px;
+					background-color: white;
+					transition: 0.2s;
+					border-radius: 50%;
+				}
+
+				input:checked + .slider {
 					background-color: var(--primary-color);
-					position: absolute;
+				}
+
+				input:focus + .slider {
+					box-shadow: 0 0 1px var(--primary-color);
+				}
+
+				input:checked + .slider:before {
+					transform: translateX(16px);
 				}
 			}
 

+ 16 - 6
frontend/src/components/AddToPlaylistDropdown.vue

@@ -20,6 +20,7 @@
 		<template #trigger>
 			<slot name="button" />
 		</template>
+
 		<div class="nav-dropdown-items" v-if="playlists.length > 0">
 			<button
 				class="nav-item"
@@ -30,12 +31,15 @@
 				:title="playlist.displayName"
 			>
 				<p class="control is-expanded checkbox-control">
-					<input
-						type="checkbox"
-						:id="index"
-						:checked="hasSong(playlist)"
-						@click="toggleSongInPlaylist(index)"
-					/>
+					<label class="switch">
+						<input
+							type="checkbox"
+							:id="index"
+							:checked="hasSong(playlist)"
+							@click="toggleSongInPlaylist(index)"
+						/>
+						<span class="slider round"></span>
+					</label>
 					<label :for="index">
 						<span></span>
 						<p>{{ playlist.displayName }}</p>
@@ -148,3 +152,9 @@ export default {
 	}
 };
 </script>
+
+<style lang="scss" scoped>
+.nav-dropdown-items button .control {
+	margin-bottom: 0 !important;
+}
+</style>

+ 98 - 52
frontend/src/pages/Settings/Tabs/Preferences.vue

@@ -7,51 +7,76 @@
 		<hr class="section-horizontal-rule" />
 
 		<p class="control is-expanded checkbox-control">
-			<input type="checkbox" id="nightmode" v-model="localNightmode" />
+			<label class="switch">
+				<input
+					type="checkbox"
+					id="nightmode"
+					v-model="localNightmode"
+				/>
+				<span class="slider round"></span>
+			</label>
+
 			<label for="nightmode">
-				<span></span>
 				<p>Use nightmode</p>
 			</label>
 		</p>
+
 		<p class="control is-expanded checkbox-control">
-			<input
-				type="checkbox"
-				id="autoSkipDisliked"
-				v-model="localAutoSkipDisliked"
-			/>
+			<label class="switch">
+				<input
+					type="checkbox"
+					id="autoSkipDisliked"
+					v-model="localAutoSkipDisliked"
+				/>
+				<span class="slider round"></span>
+			</label>
+
 			<label for="autoSkipDisliked">
-				<span></span>
 				<p>Automatically vote to skip disliked songs</p>
 			</label>
 		</p>
+
 		<p class="control is-expanded checkbox-control">
-			<input
-				type="checkbox"
-				id="activityLogPublic"
-				v-model="localActivityLogPublic"
-			/>
+			<label class="switch">
+				<input
+					type="checkbox"
+					id="activityLogPublic"
+					v-model="localActivityLogPublic"
+				/>
+				<span class="slider round"></span>
+			</label>
+
 			<label for="activityLogPublic">
-				<span></span>
 				<p>Allow my activity log to be viewed publicly</p>
 			</label>
 		</p>
+
 		<p class="control is-expanded checkbox-control">
-			<input
-				type="checkbox"
-				id="anonymousSongRequests"
-				v-model="localAnonymousSongRequests"
-			/>
+			<label class="switch">
+				<input
+					type="checkbox"
+					id="anonymousSongRequests"
+					v-model="localAnonymousSongRequests"
+				/>
+				<span class="slider round"></span>
+			</label>
+
 			<label for="anonymousSongRequests">
 				<span></span>
 				<p>Request songs anonymously</p>
 			</label>
 		</p>
+
 		<p class="control is-expanded checkbox-control">
-			<input
-				type="checkbox"
-				id="activityWatch"
-				v-model="localActivityWatch"
-			/>
+			<label class="switch">
+				<input
+					type="checkbox"
+					id="activityWatch"
+					v-model="localActivityWatch"
+				/>
+				<span class="slider round"></span>
+			</label>
+
 			<label for="activityWatch">
 				<span></span>
 				<p>Use ActivityWatch integration (requires extension)</p>
@@ -169,41 +194,62 @@ export default {
 
 <style lang="scss" scoped>
 .checkbox-control {
-	input[type="checkbox"] {
+	display: flex;
+	flex-direction: row;
+	align-items: center;
+
+	p {
+		margin-left: 10px;
+	}
+
+	.switch {
+		position: relative;
+		display: inline-block;
+		flex-shrink: 0;
+		width: 40px;
+		height: 24px;
+	}
+
+	.switch input {
 		opacity: 0;
-		position: absolute;
+		width: 0;
+		height: 0;
 	}
 
-	label {
-		display: flex;
-		flex-direction: row;
-		align-items: center;
-
-		span {
-			cursor: pointer;
-			width: 24px;
-			height: 24px;
-			background-color: var(--white);
-			display: inline-block;
-			border: 1px solid var(--dark-grey-2);
-			position: relative;
-			border-radius: 3px;
-		}
-
-		p {
-			margin-left: 10px;
-		}
+	.slider {
+		position: absolute;
+		cursor: pointer;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		background-color: #ccc;
+		transition: 0.2s;
+		border-radius: 34px;
 	}
 
-	input[type="checkbox"]:checked + label span::after {
+	.slider:before {
+		position: absolute;
 		content: "";
-		width: 18px;
-		height: 18px;
-		left: 2px;
-		top: 2px;
-		border-radius: 3px;
+		height: 16px;
+		width: 16px;
+		left: 4px;
+		bottom: 4px;
+		background-color: white;
+		transition: 0.2s;
+		border-radius: 50%;
+	}
+
+	input:checked + .slider {
 		background-color: var(--primary-color);
-		position: absolute;
+	}
+
+	input:focus + .slider {
+		box-shadow: 0 0 1px var(--primary-color);
+	}
+
+	input:checked + .slider:before {
+		transform: translateX(16px);
 	}
 }
 </style>

+ 2 - 1
frontend/src/pages/Settings/index.vue

@@ -162,7 +162,7 @@ export default {
 		flex-direction: column;
 	}
 
-	@media only screen and (min-width: 900px) {
+	@media only screen and (min-width: 700px) {
 		#page-title {
 			margin: 0;
 			font-size: 40px;
@@ -170,6 +170,7 @@ export default {
 
 		#sidebar-with-content {
 			width: 962px;
+			max-width: 100%;
 			margin: 0 auto;
 			margin-top: 30px;
 			flex-direction: row;