Spaces:
Running
Running
Fix loopy submission format and pattern layout
Browse files- frontend/src/components/PuzzleEditor.tsx +30 -29
- frontend/src/index.css +15 -14
frontend/src/components/PuzzleEditor.tsx
CHANGED
|
@@ -803,8 +803,8 @@ function PatternEditor({ boardAscii, onChange }: Omit<Props, "puzzleType">) {
|
|
| 803 |
<div className="editor-stack">
|
| 804 |
<div className="puzzle-note">Every cell starts white. Click a square to toggle it between white and filled black.</div>
|
| 805 |
<div className="pattern-layout">
|
| 806 |
-
<div className="pattern-top-
|
| 807 |
-
|
| 808 |
{columnClues.map((column, index) => (
|
| 809 |
<div
|
| 810 |
key={`column-${index}`}
|
|
@@ -822,35 +822,36 @@ function PatternEditor({ boardAscii, onChange }: Omit<Props, "puzzleType">) {
|
|
| 822 |
</div>
|
| 823 |
))}
|
| 824 |
</div>
|
| 825 |
-
|
| 826 |
-
{
|
| 827 |
-
<div
|
| 828 |
-
|
| 829 |
-
|
| 830 |
-
|
| 831 |
-
|
| 832 |
-
|
| 833 |
-
|
| 834 |
-
|
| 835 |
-
|
| 836 |
-
</span>
|
| 837 |
-
))}
|
| 838 |
-
</div>
|
| 839 |
-
<div className="board-grid pattern-board" style={{ gridTemplateColumns: `repeat(${row.cells.length}, 46px)` }}>
|
| 840 |
-
{row.cells.map((cell, cellIndex) => (
|
| 841 |
-
<button
|
| 842 |
-
key={`${rowIndex}-${cellIndex}`}
|
| 843 |
-
type="button"
|
| 844 |
-
className={`board-square ${cell === "##" ? "fill" : "empty"}`}
|
| 845 |
-
onClick={() => cycle(rowIndex, cellIndex)}
|
| 846 |
-
>
|
| 847 |
-
{cell === "##" ? "■" : ""}
|
| 848 |
-
</button>
|
| 849 |
))}
|
| 850 |
-
</div>
|
| 851 |
</div>
|
| 852 |
-
|
| 853 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 854 |
</div>
|
| 855 |
</div>
|
| 856 |
);
|
|
|
|
| 803 |
<div className="editor-stack">
|
| 804 |
<div className="puzzle-note">Every cell starts white. Click a square to toggle it between white and filled black.</div>
|
| 805 |
<div className="pattern-layout">
|
| 806 |
+
<div className="pattern-top-spacer" />
|
| 807 |
+
<div className="pattern-top-clues" style={{ gridTemplateColumns: `repeat(${columnClues.length}, 46px)` }}>
|
| 808 |
{columnClues.map((column, index) => (
|
| 809 |
<div
|
| 810 |
key={`column-${index}`}
|
|
|
|
| 822 |
</div>
|
| 823 |
))}
|
| 824 |
</div>
|
| 825 |
+
{template.rows.map((row, rowIndex) => (
|
| 826 |
+
<div key={`row-wrap-${rowIndex}`} className="pattern-row-pair">
|
| 827 |
+
<div className="pattern-clue pattern-row-clue">
|
| 828 |
+
{row.prefix
|
| 829 |
+
.trim()
|
| 830 |
+
.split(/\s+/)
|
| 831 |
+
.filter(Boolean)
|
| 832 |
+
.map((clue, clueIndex) => (
|
| 833 |
+
<span key={`${rowIndex}-${clueIndex}`} className="pattern-clue-pill">
|
| 834 |
+
{clue}
|
| 835 |
+
</span>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 836 |
))}
|
|
|
|
| 837 |
</div>
|
| 838 |
+
<div
|
| 839 |
+
className="board-grid pattern-board"
|
| 840 |
+
style={{ gridTemplateColumns: `repeat(${row.cells.length}, 46px)` }}
|
| 841 |
+
>
|
| 842 |
+
{row.cells.map((cell, cellIndex) => (
|
| 843 |
+
<button
|
| 844 |
+
key={`${rowIndex}-${cellIndex}`}
|
| 845 |
+
type="button"
|
| 846 |
+
className={`board-square ${cell === "##" ? "fill" : "empty"}`}
|
| 847 |
+
onClick={() => cycle(rowIndex, cellIndex)}
|
| 848 |
+
>
|
| 849 |
+
{cell === "##" ? "■" : ""}
|
| 850 |
+
</button>
|
| 851 |
+
))}
|
| 852 |
+
</div>
|
| 853 |
+
</div>
|
| 854 |
+
))}
|
| 855 |
</div>
|
| 856 |
</div>
|
| 857 |
);
|
frontend/src/index.css
CHANGED
|
@@ -410,13 +410,25 @@ a {
|
|
| 410 |
|
| 411 |
.pattern-layout {
|
| 412 |
display: grid;
|
| 413 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 414 |
}
|
| 415 |
|
| 416 |
.pattern-top-clues {
|
| 417 |
display: grid;
|
| 418 |
-
gap:
|
| 419 |
align-items: end;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 420 |
}
|
| 421 |
|
| 422 |
.pattern-column-stack {
|
|
@@ -428,18 +440,7 @@ a {
|
|
| 428 |
|
| 429 |
.pattern-board {
|
| 430 |
padding: 10px;
|
| 431 |
-
|
| 432 |
-
|
| 433 |
-
.pattern-grid {
|
| 434 |
-
display: grid;
|
| 435 |
-
gap: 8px;
|
| 436 |
-
}
|
| 437 |
-
|
| 438 |
-
.pattern-row {
|
| 439 |
-
display: grid;
|
| 440 |
-
grid-template-columns: 92px auto;
|
| 441 |
-
gap: 12px;
|
| 442 |
-
align-items: center;
|
| 443 |
}
|
| 444 |
|
| 445 |
.pattern-clue {
|
|
|
|
| 410 |
|
| 411 |
.pattern-layout {
|
| 412 |
display: grid;
|
| 413 |
+
grid-template-columns: 92px max-content;
|
| 414 |
+
gap: 12px;
|
| 415 |
+
align-items: end;
|
| 416 |
+
width: max-content;
|
| 417 |
+
}
|
| 418 |
+
|
| 419 |
+
.pattern-top-spacer {
|
| 420 |
+
min-height: 1px;
|
| 421 |
}
|
| 422 |
|
| 423 |
.pattern-top-clues {
|
| 424 |
display: grid;
|
| 425 |
+
gap: 2px;
|
| 426 |
align-items: end;
|
| 427 |
+
justify-content: start;
|
| 428 |
+
}
|
| 429 |
+
|
| 430 |
+
.pattern-row-pair {
|
| 431 |
+
display: contents;
|
| 432 |
}
|
| 433 |
|
| 434 |
.pattern-column-stack {
|
|
|
|
| 440 |
|
| 441 |
.pattern-board {
|
| 442 |
padding: 10px;
|
| 443 |
+
width: max-content;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 444 |
}
|
| 445 |
|
| 446 |
.pattern-clue {
|