Style the colour picker
This commit is contained in:
		
							parent
							
								
									47a657a36c
								
							
						
					
					
						commit
						f213a499e2
					
				| @ -34,15 +34,7 @@ | |||||||
| 					<li><a href="/links">Links</a></li> | 					<li><a href="/links">Links</a></li> | ||||||
| 				</ul> | 				</ul> | ||||||
| 			</nav> | 			</nav> | ||||||
| 			<color-scheme-toggle></color-scheme-toggle> | 			<fieldset class="color-scheme"> | ||||||
| 		</header> |  | ||||||
| 		{{ content | safe }} |  | ||||||
| 		<footer> |  | ||||||
| 			<div class="wrapper-lg">Copyright © {{ today.year }} {{ metadata.author.name }}</div> |  | ||||||
| 		</footer> |  | ||||||
| 
 |  | ||||||
| 		<template id="color-scheme-toggle"> |  | ||||||
| 			<fieldset> |  | ||||||
| 				<legend>Change your colour scheme</legend> | 				<legend>Change your colour scheme</legend> | ||||||
| 				<label> | 				<label> | ||||||
| 					<input type="radio" name="color-scheme" value="dark" /> | 					<input type="radio" name="color-scheme" value="dark" /> | ||||||
| @ -53,55 +45,50 @@ | |||||||
| 					Light | 					Light | ||||||
| 				</label> | 				</label> | ||||||
| 			</fieldset> | 			</fieldset> | ||||||
| 		</template> | 		</header> | ||||||
|  | 		{{ content | safe }} | ||||||
|  | 		<footer> | ||||||
|  | 			<div class="wrapper-lg">Copyright © {{ today.year }} {{ metadata.author.name }}</div> | ||||||
|  | 		</footer> | ||||||
|  | 
 | ||||||
|  | 		 | ||||||
| 		<script type="text/javascript"> | 		<script type="text/javascript"> | ||||||
| 			window.customElements.define("color-scheme-toggle", class extends HTMLElement { | 			const defaultColourScheme = () => { | ||||||
| 				constructor() { | 				if (localStorage.getItem('color-scheme')) { | ||||||
| 					super(); | 					return localStorage.getItem('color-scheme'); | ||||||
| 
 |  | ||||||
| 					const template = document.getElementById("color-scheme-toggle"); |  | ||||||
| 					const templateNode = template.content.cloneNode(true); |  | ||||||
| 
 |  | ||||||
| 					this.appendChild(templateNode); |  | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				getColourScheme = () => { | 				if (window.matchMedia('(prefers-color-scheme: dark)')?.matches) { | ||||||
| 					const colourScheme = localStorage.getItem('color-scheme'); | 					return "dark"; | ||||||
| 
 |  | ||||||
| 					if (colourScheme) { |  | ||||||
| 						return colourScheme; |  | ||||||
| 					} |  | ||||||
| 
 |  | ||||||
| 					if (window.matchMedia('(prefers-color-scheme: dark)')?.matches) { |  | ||||||
| 						return "dark"; |  | ||||||
| 					} |  | ||||||
| 
 |  | ||||||
| 					return "light"; |  | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				onColourSchemeChange = (e) => { | 				return "light"; | ||||||
| 					localStorage.setItem('color-scheme', e.target.value); | 			}; | ||||||
| 					this.updateComponents(); |  | ||||||
| 				} |  | ||||||
| 
 | 
 | ||||||
| 				updateComponents = () => { | 			const data = new Proxy({ | ||||||
| 					this.querySelectorAll('[name="color-scheme"]').forEach(radio => { | 				'color-scheme': defaultColourScheme(), | ||||||
| 						radio.checked = this.getColourScheme() === radio.value; | 			}, { | ||||||
|  | 				set: (obj, key, value) => { | ||||||
|  | 					obj[key] = value; | ||||||
|  | 					localStorage.setItem(key, value); | ||||||
|  | 					document.querySelectorAll(`[type="radio"][name="${key}"]`).forEach(radio => { | ||||||
|  | 						radio.checked = radio.value === value; | ||||||
| 					}); | 					}); | ||||||
|  | 					document.body.setAttribute(`data-${key}`, value); | ||||||
| 
 | 
 | ||||||
| 					if (localStorage.getItem('color-scheme')) { | 					return true; | ||||||
| 						document.body.setAttribute('data-color-scheme', this.getColourScheme()); |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				connectedCallback() { |  | ||||||
| 					this.querySelectorAll('[name="color-scheme"]').forEach(radio => { |  | ||||||
| 						radio.addEventListener('change', this.onColourSchemeChange); |  | ||||||
| 					}); |  | ||||||
| 
 |  | ||||||
| 					this.updateComponents(); |  | ||||||
| 				} | 				} | ||||||
| 			}); | 			}); | ||||||
|  | 
 | ||||||
|  | 			const onRadioChange = e => { | ||||||
|  | 				data[e.target.name] = e.target.value; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			document.querySelectorAll('[name="color-scheme"]').forEach(radio => { | ||||||
|  | 				radio.addEventListener('change', onRadioChange); | ||||||
|  | 				radio.checked = data[radio.name] == radio.value; | ||||||
|  | 			}); | ||||||
|  | 			document.body.setAttribute(`data-color-scheme`, data['color-scheme']); | ||||||
| 		</script> | 		</script> | ||||||
| 	</body> | 	</body> | ||||||
| </html> | </html> | ||||||
|  | |||||||
							
								
								
									
										42
									
								
								src/css/exceptions/color-scheme-picker.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/css/exceptions/color-scheme-picker.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | |||||||
|  | .color-scheme { | ||||||
|  | 	border: 0; | ||||||
|  | 	display: flex; | ||||||
|  | 	gap: var(--space-size-xs); | ||||||
|  | 
 | ||||||
|  | 	legend { | ||||||
|  | 		position:absolute; | ||||||
|  | 		clip:rect(0 0 0 0); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	input[name="color-scheme"] { | ||||||
|  | 		position:absolute; | ||||||
|  | 		clip:rect(0 0 0 0); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	label:has(:not(:checked)) { | ||||||
|  | 		color: var(--color-subtle); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	label:has(:focus-visible) { | ||||||
|  | 		outline: 1px solid var(--color-primary); | ||||||
|  | 		outline-offset: 2px; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	label:has([name="color-scheme"])::before { | ||||||
|  | 		font-family: "font awesome 6 free"; | ||||||
|  |         font-style: normal; | ||||||
|  |         font-variant: normal; | ||||||
|  |         text-rendering: auto; | ||||||
|  |         font-weight: 900; | ||||||
|  |         -webkit-font-smoothing: antialiased; | ||||||
|  |         font-size: var(--text-size-s); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	label:has([name="color-scheme"][value="dark"])::before { | ||||||
|  | 		content: "\f186"; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	label:has([name="color-scheme"][value="light"])::before { | ||||||
|  | 		content: "\f185"; | ||||||
|  | 	} | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user