beginning of interface
This commit is contained in:
parent
420d719fc1
commit
ef08eea8d9
3 changed files with 93 additions and 20 deletions
50
src/App.css
50
src/App.css
|
@ -1,10 +1,3 @@
|
|||
.logo.vite:hover {
|
||||
filter: drop-shadow(0 0 2em #747bff);
|
||||
}
|
||||
|
||||
.logo.solid:hover {
|
||||
filter: drop-shadow(0 0 2em #2f5d90);
|
||||
}
|
||||
:root {
|
||||
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
|
@ -30,22 +23,43 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 6em;
|
||||
padding: 1.5em;
|
||||
will-change: filter;
|
||||
transition: 0.75s;
|
||||
}
|
||||
|
||||
.logo.tauri:hover {
|
||||
filter: drop-shadow(0 0 2em #24c8db);
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.puzzle {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1vmin;
|
||||
font-size: 3vmin;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.puzzle-row {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 15vmin;
|
||||
gap: 1vmin;
|
||||
}
|
||||
.puzzle-item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
width: 20vmin;
|
||||
border-radius: 1vmin;
|
||||
flex-grow: 0;
|
||||
background-color: #f6f6f622;
|
||||
}
|
||||
.puzzle-item:hover, .puzzle-item:focus-visible {
|
||||
background-color: #f6f6f633;
|
||||
}
|
||||
.puzzle-item.is-selected {
|
||||
outline: 0.33vmin solid #ffffffdd;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
|
|
55
src/App.tsx
55
src/App.tsx
|
@ -1,12 +1,63 @@
|
|||
import { createSignal } from "solid-js";
|
||||
// import logo from "./assets/logo.svg";
|
||||
import { For, createMemo, createSignal } from "solid-js";
|
||||
import connections from "./assets/connections.json";
|
||||
import "./App.css";
|
||||
import { shuffleArray } from "./utils";
|
||||
|
||||
function fromIndex(index: number): [number, number] {
|
||||
const col = index % 4;
|
||||
const row = (index - col) / 4;
|
||||
return [row, col];
|
||||
}
|
||||
|
||||
function App() {
|
||||
const [puzzleIndex, setPuzzleIndex] = createSignal(0);
|
||||
const [selected, setSelected] = createSignal<number[]>([]);
|
||||
const puzzle = createMemo(() =>
|
||||
shuffleArray(
|
||||
Array(16)
|
||||
.fill(0)
|
||||
.map((_, i) => i)
|
||||
)
|
||||
);
|
||||
const answers = () => connections[puzzleIndex()].answers;
|
||||
|
||||
return (
|
||||
<main class="container">
|
||||
<h1>Slick Connections</h1>
|
||||
<div class="puzzle">
|
||||
<For each={[0, 1, 2, 3]}>
|
||||
{(row) => (
|
||||
<div class="puzzle-row">
|
||||
<For each={[0, 1, 2, 3]}>
|
||||
{(col) => {
|
||||
const index = 4 * row + col;
|
||||
const puzzleIndex = puzzle()[index];
|
||||
const [groupIndex, memberIndex] = fromIndex(puzzleIndex);
|
||||
const answer = answers()[groupIndex].members[memberIndex];
|
||||
return (
|
||||
<div
|
||||
classList={{
|
||||
"puzzle-item": true,
|
||||
"is-selected": selected().includes(index),
|
||||
}}
|
||||
tabindex="0"
|
||||
on:click={() => {
|
||||
setSelected(
|
||||
selected().includes(index)
|
||||
? selected().filter(x => x !== index)
|
||||
: [...selected(), index]
|
||||
);
|
||||
}}
|
||||
>
|
||||
{answer}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</For>
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
|
8
src/utils.ts
Normal file
8
src/utils.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
export function shuffleArray<T>(array: T[]) {
|
||||
const copy = Array.from(array)
|
||||
for (let i = copy.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[copy[i], copy[j]] = [copy[j], copy[i]];
|
||||
}
|
||||
return copy
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue