mirror of
https://github.com/Motschen/midnightdust-eu.git
synced 2025-12-15 18:15:10 +01:00
Add many interactive components
- Version selector for MidnightLib is now finally working - Added buttons to copy code from code blocks - Added color chooser in Puzzle wiki
This commit is contained in:
71
src/components/ColorPicker.astro
Normal file
71
src/components/ColorPicker.astro
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
interface Props {
|
||||
includeHashtag?: boolean
|
||||
}
|
||||
const { includeHashtag } = Astro.props
|
||||
import { Icon } from 'astro-icon/components'
|
||||
---
|
||||
|
||||
<section class="my-6">
|
||||
<div class="">
|
||||
<p class="text-lg">Select a color below to get the hex code:</p>
|
||||
<div class="flex">
|
||||
<fieldset>
|
||||
<input
|
||||
type="color"
|
||||
id="color-select"
|
||||
class="h-16 w-48 hover:cursor-pointer rounded-xl border-neutral-900 dark:border-neutral-100 border-4"
|
||||
/>
|
||||
</fieldset>
|
||||
<button
|
||||
id="copy-button"
|
||||
class="button has-icon color-secondary ml-3 rounded-md text-white hover:cursor-pointer appearance-none h-16">
|
||||
<Icon id="copy-icon" name="ion:copy-outline" />
|
||||
<Icon id="success-icon" name="ion:checkmark-outline" class="hidden" />
|
||||
<p id="color-label">{includeHashtag ? '#' : ''}000000</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
// Get the 2 elements from above
|
||||
const colorLabel = document.getElementById("color-label");
|
||||
const colorSelect = document.getElementById("color-select");
|
||||
const copyButton = document.getElementById("copy-button");
|
||||
|
||||
const copyIcon = document.getElementById("copy-icon");
|
||||
const successIcon = document.getElementById("success-icon");
|
||||
|
||||
colorSelect?.addEventListener("change", async (e) => {
|
||||
const {
|
||||
target: { value }, // Returns the chosen color (already in hex format :D)
|
||||
} = e;
|
||||
if (colorLabel) colorLabel.innerText = colorLabel.innerText.startsWith('#') ? value : value.replace('#', '');
|
||||
});
|
||||
|
||||
// Add event listener to copy the color to the clipboard
|
||||
if (colorLabel) copyButton?.addEventListener('click', () => copyString(colorLabel.innerText, copyButton));
|
||||
|
||||
|
||||
async function copyString(text: string, button: HTMLElement) {
|
||||
await navigator.clipboard.writeText(text);
|
||||
|
||||
// visual feedback that task is completed
|
||||
if (button) {
|
||||
button.style.backgroundColor = "#"+text.replace('#', '');
|
||||
button.style.borderColor = "#"+text.replace('#', '');
|
||||
}
|
||||
if (copyIcon) copyIcon.style.display = 'none';
|
||||
if (successIcon) successIcon.style.display = 'initial';
|
||||
|
||||
setTimeout(() => {
|
||||
if (button) {
|
||||
button.style.backgroundColor = 'var(--secondary-100)';
|
||||
button.style.borderColor = 'var(--secondary-100)';
|
||||
}
|
||||
if (copyIcon) copyIcon.style.display = 'initial';
|
||||
if (successIcon) successIcon.style.display = 'none';
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
</script>
|
||||
@@ -1,161 +1,68 @@
|
||||
---
|
||||
import { loaderList, versionList, selectedLoader, selectedVersion, getResultingVersion } from '../js/modversion.js'
|
||||
import { Icon } from 'astro-icon/components'
|
||||
import { loaderList, versionList} from '../js/modversion.js'
|
||||
---
|
||||
|
||||
<div id="version-dropdown">
|
||||
<div class="container">
|
||||
<div class="">
|
||||
<div class="wrapper">
|
||||
<label for="loader-selector" class="sr-only">Select the Modloader</label>
|
||||
<select
|
||||
x-data="{
|
||||
loader: localStorage.selectedLoader || 'fabric',
|
||||
switchLoader: function (newValue) {
|
||||
localStorage.selectedLoader = newValue;
|
||||
console.log('New loader: ' + localStorage.selectedLoader);
|
||||
},
|
||||
}"
|
||||
name="loader-selector"
|
||||
id="loader-selector"
|
||||
class="appearance-none cursor-pointer rounded-md pl-3 pr-2 py-1.5 dark:bg-stone-950 dark:text-white focus-visible:outline-none"
|
||||
x-model="loader"
|
||||
aria-label="Choose the Modloader"
|
||||
@change="switchLoader($event.target.value)">
|
||||
class="selector cursor-pointer rounded-md pl-3 pr-2 py-1.5 border-2 dark:border-green-300 dark:bg-neutral-800 dark:text-white focus-visible:outline-none"
|
||||
aria-label="Choose the Modloader">
|
||||
{ loaderList.map((loader) =>
|
||||
<option value={loader}>{loader.charAt(0).toUpperCase() + loader.slice(1)}</option>
|
||||
<option value={loader}>{loader.charAt(0).toUpperCase() + loader.replace("neoforge", "NeoForge").slice(1)}</option>
|
||||
)}
|
||||
</select>
|
||||
<label for="version-selector" class="sr-only">Select the Version</label>
|
||||
<select
|
||||
x-data="{
|
||||
version: localStorage.selectedVersion || '1.21.1',
|
||||
switchVersion: function (newValue) {
|
||||
localStorage.selectedVersion = newValue;
|
||||
console.log('New version: ' + localStorage.selectedVersion);
|
||||
console.log(getResultingVersion);
|
||||
},
|
||||
}"
|
||||
name="version-selector"
|
||||
id="version-selector"
|
||||
class="appearance-none cursor-pointer rounded-md pl-3 pr-2 py-1.5 dark:bg-stone-950 dark:text-white focus-visible:outline-none"
|
||||
x-model="version"
|
||||
aria-label="Choose the Version"
|
||||
@change="switchVersion($event.target.value)">
|
||||
class="selector cursor-pointer rounded-md ml-2 pl-3 pr-2 py-1.5 border-2 dark:border-green-300 dark:bg-neutral-800 dark:text-white focus-visible:outline-none"
|
||||
aria-label="Choose the Version">
|
||||
{ versionList.map((version) =>
|
||||
<option value={version}>{version}</option>
|
||||
)}
|
||||
<Icon name="ion:copy-outline"></Icon>
|
||||
</select>
|
||||
<label for="version-selector" x-text="">{}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
import { getResultingVersion, setGameVersion, setLoaderVersion } from "../js/modversion";
|
||||
// Get the gradle.properties code block
|
||||
const versionLabel = document.getElementById("midnightlib-version");
|
||||
// Get the 2 selectors defined above
|
||||
const loaderSelector = document.getElementById("loader-selector");
|
||||
const versionSelector = document.getElementById("version-selector");
|
||||
|
||||
loaderSelector?.addEventListener("change", async (e) => {
|
||||
const {
|
||||
target: { value }, // Returns the current loader string
|
||||
} = e;
|
||||
|
||||
setLoaderVersion(value);
|
||||
if (versionLabel) versionLabel.innerText = `midnightlib_version = `+getResultingVersion();
|
||||
});
|
||||
versionSelector?.addEventListener("change", async (e) => {
|
||||
const {
|
||||
target: { value }, // Returns the current version string
|
||||
} = e;
|
||||
|
||||
setGameVersion(value);
|
||||
if (versionLabel) versionLabel.innerText = `midnightlib_version = `+getResultingVersion();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" is:global>
|
||||
@use '../assets/scss/base/breakpoint' as *;
|
||||
@use '../assets/scss/base/outline' as *;
|
||||
|
||||
#version-dropdown {
|
||||
> .container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
|
||||
.wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
> ul {
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
list-style-type: none;
|
||||
|
||||
a,
|
||||
button {
|
||||
text-decoration: none;
|
||||
font-size: 1.125rem;
|
||||
line-height: 1.6875rem;
|
||||
}
|
||||
|
||||
a:hover,
|
||||
a:focus,
|
||||
.is-active,
|
||||
.has-version-dropdown > button:hover,
|
||||
.has-version-dropdown > button:focus {
|
||||
text-decoration: underline;
|
||||
text-decoration-thickness: 1px;
|
||||
text-decoration-style: wavy;
|
||||
text-underline-offset: 7px;
|
||||
}
|
||||
|
||||
.is-active {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.has-version-dropdown {
|
||||
position: relative;
|
||||
|
||||
> button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0;
|
||||
margin-top: -1px;
|
||||
border: none;
|
||||
color: var(--action-color);
|
||||
|
||||
&:hover {
|
||||
color: var(--action-color-state);
|
||||
|
||||
&::after {
|
||||
border-color: var(--action-color-state);
|
||||
}
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
width: 0.85rem;
|
||||
height: 0.75em;
|
||||
margin-top: -0.25rem;
|
||||
border-style: solid;
|
||||
border-width: 0.2em 0.2em 0 0;
|
||||
border-color: var(--action-color);
|
||||
transform: rotate(135deg);
|
||||
}
|
||||
|
||||
&.show {
|
||||
&::after {
|
||||
margin-top: 0.25rem;
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
~ ul {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
display: none;
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
min-width: 260px;
|
||||
top: 125%;
|
||||
right: 0;
|
||||
bottom: auto;
|
||||
left: 0;
|
||||
padding: 1rem;
|
||||
background-color: var(--neutral-background);
|
||||
border: 2px solid black;
|
||||
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
}
|
||||
#loader-selector::after {
|
||||
content: "v";
|
||||
}
|
||||
.selector:is(.darkmode *) {
|
||||
background-color: var(--dark-100);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -3,6 +3,44 @@ import DefaultLayout from './DefaultLayout.astro'
|
||||
|
||||
const { frontmatter } = Astro.props
|
||||
---
|
||||
<!-- Copy Code Buttons based on: https://timneubauer.dev/blog/copy-code-button-in-astro/ -->
|
||||
<script>
|
||||
let copyButtonLabel = "Copy Code";
|
||||
let codeBlocks = Array.from(document.querySelectorAll("pre"));
|
||||
|
||||
for (let codeBlock of codeBlocks) {
|
||||
let wrapper = document.createElement("div");
|
||||
wrapper.style.position = "relative";
|
||||
|
||||
let copyButton = document.createElement("button");
|
||||
copyButton.className = "copy-code";
|
||||
copyButton.innerHTML = copyButtonLabel;
|
||||
|
||||
codeBlock.setAttribute("tabindex", "0");
|
||||
codeBlock.appendChild(copyButton);
|
||||
// wrap codebock with relative parent element
|
||||
if (codeBlock.parentNode) codeBlock.parentNode.insertBefore(wrapper, codeBlock);
|
||||
wrapper.appendChild(codeBlock);
|
||||
|
||||
copyButton.addEventListener("click", async () => {
|
||||
await copyCode(codeBlock, copyButton);
|
||||
});
|
||||
}
|
||||
|
||||
async function copyCode(block, button) {
|
||||
let code = block.querySelector("code");
|
||||
let text = code.innerText;
|
||||
|
||||
await navigator.clipboard.writeText(text);
|
||||
|
||||
// visual feedback that task is completed
|
||||
button.innerText = "Code Copied!";
|
||||
|
||||
setTimeout(() => {
|
||||
button.innerText = copyButtonLabel;
|
||||
}, 700);
|
||||
}
|
||||
</script>
|
||||
|
||||
<DefaultLayout title={frontmatter.title}>
|
||||
<div class="container">
|
||||
@@ -11,3 +49,35 @@ const { frontmatter } = Astro.props
|
||||
</div>
|
||||
</div>
|
||||
</DefaultLayout>
|
||||
|
||||
<style is:global>
|
||||
.copy-code {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
background-color: var(--primary-300);
|
||||
color: var(--neutral-100);
|
||||
padding: 0.25rem 0.5rem;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
border: none;
|
||||
border-top-right-radius: 0.35rem;
|
||||
border-bottom-left-radius: 0.35rem;
|
||||
box-shadow: -1px 1px 8px var(--primary-300);
|
||||
}
|
||||
.copy-code:is(.darkmode *) {
|
||||
background-color: var(--secondary-100);
|
||||
color: var(--dark-100);
|
||||
box-shadow: -1px 1px 8px var(--secondary-100);
|
||||
}
|
||||
|
||||
.copy-code:hover {
|
||||
background-color: var(--primary-500);
|
||||
box-shadow: -1px 1px 8px var(--primary-500);
|
||||
}
|
||||
.copy-code:hover:is(.darkmode *) {
|
||||
background-color: var(--secondary-500);
|
||||
box-shadow: -1px 1px 8px var(--secondary-500);
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -33,14 +33,13 @@ dependencies {
|
||||
```
|
||||
### `gradle.properties`
|
||||
<VersionDropdown></VersionDropdown>
|
||||
{<pre><code className="language-java">midnightlib_version = {getResultingVersion()}</code></pre>}
|
||||
{<pre><code className="language-java" id="midnightlib-version" >midnightlib_version = {getResultingVersion()}</code></pre>}
|
||||
|
||||
<Notification type="info">
|
||||
<Icon name="ion:information-circle-outline" />
|
||||
<p>
|
||||
<strong>Info:</strong> You should always pick the version that suits your modloader and Minecraft version best.
|
||||
The version selector is currently still WIP.
|
||||
Find all available versions on [Modrinth](https://www.modrinth.com/mod/midnightlib/versions)
|
||||
The version selector is finally fully functional!
|
||||
</p>
|
||||
</Notification>
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ layout: ../../layouts/MarkdownLayout.astro
|
||||
title: Puzzle Wiki
|
||||
---
|
||||
|
||||
import ColorPicker from '../../components/ColorPicker.astro'
|
||||
import { Icon } from 'astro-icon/components'
|
||||
import { Notification } from 'accessible-astro-components'
|
||||
|
||||
@@ -51,7 +52,7 @@ screen.loading.blend=off
|
||||
|
||||
### Entering the world of color
|
||||
The world would be a sad place without colors.
|
||||
That's why Puzzle allows you to customize them to your heart's content.
|
||||
That's why Puzzle allows you to customize them to your heart's content!
|
||||
Custom colors can be defined in the `assets/minecraft/optifine/color.properties` file.
|
||||
|
||||
```properties
|
||||
@@ -69,11 +70,12 @@ screen.loading.bar=313244
|
||||
<Notification type="default">
|
||||
<Icon name="ion:information-circle-outline" />
|
||||
<p>
|
||||
<strong>Info:</strong> Colors have to be defined using hex color codes.
|
||||
You can use websites like <strong>[this](https://redketchup.io/color-picker)</strong> one to find nice hex color codes.
|
||||
<strong>Info:</strong> Colors have to be defined using hex color codes (without the #).
|
||||
You can use the color picker below to find the perfect color.
|
||||
The example colors are based on the <strong>[Catppuccin Mocha](https://github.com/catppuccin/catppuccin)</strong> color pallette.
|
||||
</p>
|
||||
</Notification>
|
||||
<ColorPicker/>
|
||||
|
||||
<center><img alt="The Puzzle logo on a dark background with pastel colors" src="/puzzle/custom-colors.webp" width="650"></img></center>
|
||||
<p class="text-center italic">Dark mode! Finally, my eyes can rest.</p>
|
||||
|
||||
Reference in New Issue
Block a user