Updated to Astro 5. Cruft removed.
This commit is contained in:
parent
510ecc2094
commit
97c36c6a42
11 changed files with 819 additions and 1344 deletions
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
import { getImage } from "astro:assets";
|
||||
import HoustonGrad from "~/assets/houston_grad.png";
|
||||
// import { getImage } from "astro:assets";
|
||||
// import HoustonGrad from "~/assets/houston_grad.png";
|
||||
|
||||
export interface Props {
|
||||
icon?: "puzzle-piece" | "question-mark" | "check-list";
|
||||
|
|
|
|||
|
|
@ -1,108 +0,0 @@
|
|||
<div class="checklist"><slot /></div>
|
||||
{
|
||||
Astro.slots.has('alternative') && (
|
||||
<>
|
||||
<p class="or">
|
||||
foo
|
||||
</p>
|
||||
<div class="checklist alternative">
|
||||
<slot name="alternative" />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
<style>
|
||||
check-list > * + * {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.checklist > :global(ul) {
|
||||
list-style: none;
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
|
||||
check-list :global(label) {
|
||||
display: block;
|
||||
position: relative;
|
||||
margin: 0 -1rem !important;
|
||||
border-radius: 0.5rem;
|
||||
padding-block: 0.5rem;
|
||||
padding-inline: 3.5rem 0.5rem;
|
||||
cursor: pointer;
|
||||
font-size: var(--sl-text-lg);
|
||||
color: var(--sl-color-green-high);
|
||||
}
|
||||
|
||||
check-list :global(label span) {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
check-list :global(input[type='checkbox']) {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
check-list :global(input[type='checkbox']:focus) {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
check-list :global(input[type='checkbox']::after) {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset-inline-start: 1rem;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
transform-origin: center;
|
||||
text-align: center;
|
||||
line-height: 1.25;
|
||||
width: 1.25em;
|
||||
height: 1.25em;
|
||||
font-size: 1.25em;
|
||||
border: 1px solid var(--sl-color-green-high);
|
||||
border-radius: 0.25rem;
|
||||
color: var(--sl-color-green);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
check-list :global(input[type='checkbox']:focus::after) {
|
||||
outline: 3px solid var(--sl-color-green);
|
||||
outline-offset: 0.5rem;
|
||||
}
|
||||
|
||||
check-list :global(input[type='checkbox']:not(:focus-visible)::after) {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
check-list :global(label:has(> input[type='checkbox']:checked)) {
|
||||
color: var(--sl-color-white);
|
||||
}
|
||||
|
||||
check-list :global(input[type='checkbox']:checked::after) {
|
||||
content: url("data:image/svg+xml,%3Csvg width='28' height='28' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Crect width='24' height='24' rx='4' fill='white'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M20.0946 6.02558C20.6992 6.592 20.7301 7.54124 20.1636 8.14578L10.3868 18.5806C9.55548 19.468 8.14726 19.468 7.3159 18.5806L4.02558 15.0689C3.45917 14.4643 3.49008 13.5151 4.09461 12.9487C4.69915 12.3822 5.6484 12.4132 6.21481 13.0177L8.85137 15.8317L17.9744 6.09461C18.5408 5.49007 19.4901 5.45917 20.0946 6.02558Z' fill='%232F4D22'/%3E%3C/svg%3E%0A");
|
||||
border: none;
|
||||
/* color: var(--sl-color-green-low); */
|
||||
/* background-color: var(--sl-color-gray-1); */
|
||||
}
|
||||
|
||||
.or {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto 1fr;
|
||||
gap: 1em;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
color: var(--theme-text-lighter);
|
||||
}
|
||||
|
||||
.or::before,
|
||||
.or::after {
|
||||
--divider-width: 4px;
|
||||
content: '';
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
transparent calc(50% - var(--divider-width) / 2),
|
||||
var(--theme-divider) calc(50% - var(--divider-width) / 2) calc(50% + var(--divider-width) / 2),
|
||||
transparent calc(50% + var(--divider-width) / 2) 100%
|
||||
);
|
||||
}
|
||||
</style>
|
||||
|
|
@ -8,7 +8,7 @@ import Default from "@astrojs/starlight/components/Footer.astro";
|
|||
|
||||
{
|
||||
Astro.url.pathname !== "/" && (
|
||||
<script defer src="https://comentario.workaround.org/comentario.js"></script>
|
||||
<script defer is:inline src="https://comentario.workaround.org/comentario.js"></script>
|
||||
<comentario-comments no-fonts="true" id="comments"></comentario-comments>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,167 +0,0 @@
|
|||
<multiple-choice data-correct-label={"Correct"} data-incorrect-label={"Wrong"}>
|
||||
<form onsubmit="event.preventDefault()">
|
||||
<ol class="opt-list not-content"><slot /></ol>
|
||||
<div class="footer">
|
||||
<button class="submit" type="submit" disabled>
|
||||
{"Submit"}
|
||||
</button>
|
||||
<div class="answer sr-only" role="alert"></div>
|
||||
</div>
|
||||
</form>
|
||||
</multiple-choice>
|
||||
|
||||
<style>
|
||||
multiple-choice {
|
||||
display: block;
|
||||
padding-bottom: 1rem;
|
||||
color: var(--sl-color-text-accent);
|
||||
}
|
||||
|
||||
form > * + * {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.opt-list {
|
||||
list-style: none;
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
|
||||
/* .footer {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 1rem;
|
||||
} */
|
||||
|
||||
.submit,
|
||||
.answer {
|
||||
padding: 0.8rem;
|
||||
line-height: 1.4;
|
||||
max-width: 15em;
|
||||
border: 2px solid var(--sl-color-gray-4);
|
||||
}
|
||||
|
||||
.submit {
|
||||
cursor: pointer;
|
||||
color: var(--sl-color-accent);
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.submit:focus {
|
||||
background-color: hsl(224, 20%, 94%);
|
||||
}
|
||||
|
||||
.submit:not(:focus-visible) {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.submit:hover {
|
||||
background: var(--sl-color-text-accent);
|
||||
color: var(--sl-color-black);
|
||||
/* border-color: transparent; */
|
||||
}
|
||||
|
||||
.submit:disabled,
|
||||
.submit:active {
|
||||
/* transform: translateY(0.25rem); */
|
||||
}
|
||||
|
||||
.submit:disabled {
|
||||
background-color: hsl(224, 20%, 94%);
|
||||
color: hsl(224, 7%, 36%);
|
||||
opacity: 0.65;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.answer {
|
||||
text-align: center;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.correct {
|
||||
color: var(--sl-color-green-low);
|
||||
background-color: var(--sl-color-green);
|
||||
}
|
||||
|
||||
.wrong {
|
||||
color: var(--sl-color-red-low);
|
||||
background-color: var(--sl-color-red);
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
class MultipleChoice extends HTMLElement {
|
||||
#defaultCorrectLabel: string;
|
||||
#defaultIncorrectLabel: string;
|
||||
#key: string;
|
||||
#submitEl: HTMLButtonElement;
|
||||
#answerEl: HTMLParagraphElement;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.#defaultCorrectLabel = this.dataset.correctLabel!;
|
||||
this.#defaultIncorrectLabel = this.dataset.incorrectLabel!;
|
||||
this.#key = Math.random().toString();
|
||||
this.#submitEl = this.querySelector(".submit")!;
|
||||
this.#answerEl = this.querySelector(".answer")!;
|
||||
this.querySelectorAll(".opt-list > li").forEach((li) => this.#upgradeListItem(li));
|
||||
}
|
||||
|
||||
#upgradeListItem(li: Element) {
|
||||
const option = li.querySelector('input[type="radio"]') as HTMLInputElement | null;
|
||||
if (!option) return;
|
||||
|
||||
option.removeAttribute("disabled");
|
||||
option.setAttribute("name", this.#key);
|
||||
option.addEventListener("change", () => {
|
||||
this.#clearAnswer();
|
||||
this.#enableSubmit();
|
||||
});
|
||||
if (option.checked) this.#enableSubmit();
|
||||
}
|
||||
|
||||
/** Clear the answer text and hide its container visually. */
|
||||
#clearAnswer() {
|
||||
this.#answerEl.innerText = "";
|
||||
this.#answerEl.classList.remove("wrong", "correct");
|
||||
this.#answerEl.classList.add("sr-only");
|
||||
}
|
||||
|
||||
/** Show the answer result to the user. */
|
||||
#setAnswer(isCorrect: boolean) {
|
||||
const answerTemplate = this.querySelector("input:checked ~ template") as HTMLTemplateElement | null;
|
||||
if (answerTemplate) {
|
||||
this.#answerEl.replaceChildren(answerTemplate.content.cloneNode(true));
|
||||
} else {
|
||||
this.#answerEl.innerText = isCorrect ? this.#defaultCorrectLabel : this.#defaultIncorrectLabel;
|
||||
}
|
||||
this.#answerEl.classList.remove("sr-only", "wrong", "correct");
|
||||
this.#answerEl.classList.add(isCorrect ? "correct" : "wrong");
|
||||
}
|
||||
|
||||
/** Activate the submit button, preparing it to evaluate the form when clicked. */
|
||||
#enableSubmit() {
|
||||
this.#submitEl.removeAttribute("disabled");
|
||||
this.#submitEl.classList.remove("sr-only");
|
||||
this.#submitEl.onclick = () => this.#submitAnswer();
|
||||
}
|
||||
|
||||
/** Disable the submit button and hide it visually. */
|
||||
#disableSubmit() {
|
||||
this.#submitEl.setAttribute("disabled", "");
|
||||
this.#submitEl.classList.add("sr-only");
|
||||
this.#submitEl.onclick = null;
|
||||
}
|
||||
|
||||
/** Check if the selected option is correct and display the result. */
|
||||
#submitAnswer() {
|
||||
const selection = this.querySelector("input:checked") as HTMLInputElement | null;
|
||||
if (!selection) return;
|
||||
|
||||
this.#disableSubmit();
|
||||
const isCorrect = selection.dataset.isCorrect !== undefined && ["", "true"].includes(selection.dataset.isCorrect);
|
||||
this.#setAnswer(isCorrect);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("multiple-choice", MultipleChoice);
|
||||
</script>
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
---
|
||||
export interface Props {
|
||||
isCorrect?: boolean;
|
||||
}
|
||||
|
||||
const { isCorrect } = Astro.props as Props;
|
||||
---
|
||||
|
||||
<li>
|
||||
<label>
|
||||
<input type="radio" disabled data-is-correct={isCorrect} /><span><slot /></span>
|
||||
{
|
||||
Astro.slots.has('feedback') && (
|
||||
<template>
|
||||
<slot name="feedback" />
|
||||
</template>
|
||||
)
|
||||
}
|
||||
</label>
|
||||
</li>
|
||||
|
||||
<style>
|
||||
label {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
border-radius: 1rem;
|
||||
margin-inline: -0.5rem;
|
||||
padding: 0.5rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
label:hover {
|
||||
background-color: var(--sl-color-accent-low);
|
||||
}
|
||||
|
||||
input[type='radio'] {
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input[type='radio'] ~ * {
|
||||
color: var(--sl-color-text-accent);
|
||||
}
|
||||
|
||||
input[type='radio']:checked ~ * {
|
||||
color: var(--sl-color-white);
|
||||
}
|
||||
|
||||
input[type='radio']:focus::after {
|
||||
outline: 3px solid var(--sl-color-text-accent);
|
||||
outline-offset: 0.5rem;
|
||||
}
|
||||
|
||||
input[type='radio']:focus,
|
||||
input[type='radio']:not(:focus-visible)::after {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
input[type='radio']::after {
|
||||
display: block;
|
||||
content: '';
|
||||
text-align: center;
|
||||
line-height: 1.5;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
font-size: 1em;
|
||||
font-weight: 900;
|
||||
border: 2px solid var(--sl-color-accent-high);
|
||||
border-radius: 100%;
|
||||
color: var(--sl-color-white);
|
||||
box-shadow: -3px 3px var(--theme-shade-subtle);
|
||||
}
|
||||
|
||||
input[type='radio']:checked::after {
|
||||
color: hsl(var(--color-base-white), 100%);
|
||||
background-image: radial-gradient(var(--sl-color-white) 50%, transparent 0%, transparent);
|
||||
border-color: var(--sl-color-white);
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
input[type='radio']:checked::after {
|
||||
background-color: Highlight;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
---
|
||||
import type { UIDictionaryKeys } from '../i18n/translation-checkers';
|
||||
import { useTranslations } from '../i18n/util';
|
||||
|
||||
export interface Props {
|
||||
key: UIDictionaryKeys;
|
||||
}
|
||||
---
|
||||
|
||||
{useTranslations(Astro)(Astro.props.key)}
|
||||
Loading…
Add table
Add a link
Reference in a new issue