Skip to content

Instantly share code, notes, and snippets.

@dcassil
Created February 9, 2022 19:44
Show Gist options
  • Save dcassil/b8ed7cbe87993ebe627872e289dadb1f to your computer and use it in GitHub Desktop.
Save dcassil/b8ed7cbe87993ebe627872e289dadb1f to your computer and use it in GitHub Desktop.
Hello World in React
<div id="root">
<!-- This element's contents will be replaced with your component. -->
</div>
import ReactDOM from "https://cdn.skypack.dev/react-dom@17.0.1";
import * as React from "https://cdn.skypack.dev/react@17.0.1";
var decodeHtmlEntity = function (str) {
return str.replace(/&#(\d+);|&quot;/g, function (match, dec) {
return String.fromCharCode(dec);
});
};
function useCellState(initialData = {}) {
const [grid, setGrid] = React.useState(initialData);
const updateGrid = (value, cellNum, rowNum) => {
let nextGrid = { ...grid };
nextGrid[rowNum] = nextGrid[rowNum] || {};
nextGrid[rowNum][cellNum] = { ...nextGrid[rowNum][cellNum], value };
localStorage.setItem("data", JSON.stringify(nextGrid));
setGrid({ ...nextGrid });
};
const setAll = (data) => setGrid(data);
return React.useMemo(
() => ({
updateGrid,
setAll,
grid
}),
[grid]
);
}
function Cell({ cell, cellNum, rowNum, cellState, showCorrect }) {
let thisCell = cellState.grid?.[rowNum]?.[cellNum];
let isCorrect = thisCell?.value === thisCell?.letter;
let cssClass =
cell.letter === "."
? "cell blank"
: isCorrect && showCorrect
? "cell correct"
: "cell";
console.log(isCorrect, showCorrect);
return (
<th class={cssClass}>
<input
maxLength="1"
class={cssClass}
onKeyDown={(e) => {
// e.preventDefault();
const key = e.key;
if (key === "Shift" || key === "Tab") return;
if (key === "Backspace" || key === "Delete" || key === "Tab") {
if (e.target.value === "" || key === "Tab") {
e.target.parentNode.previousSibling.firstChild.focus();
}
}
}}
onKeyUp={(e) => {
const key = e.key;
console.log(key);
if (key === "Shift" || key === "Tab") return;
e.preventDefault();
if (key !== "Backspace" && key !== "Delete" && key !== "Tab") {
e.target.parentNode.nextSibling.firstChild.focus();
}
}}
onChange={(e) => {
cellState.updateGrid(e.target.value.toUpperCase(), cellNum, rowNum);
}}
value={thisCell?.value}
type="text"
/>
{thisCell?.number !== 0 && (
<span class="cellNum">{thisCell?.number}</span>
)}
</th>
);
}
function Row({ row, rowNum, cellState, showCorrect }) {
return (
<tr>
{Object.keys(row).map((cell, i) => (
<Cell
cell={row[cell]}
cellNum={cell}
rowNum={rowNum}
cellState={cellState}
showCorrect={showCorrect}
/>
))}
</tr>
);
}
function Clues({ clues, showCorrect, setShowCorrect }) {
return (
<div>
<input
id="showCorrect"
type="checkbox"
checked={showCorrect}
onChange={(e) => setShowCorrect(!showCorrect)}
/>
<label for="showCorrect">Show Correct Letters</label>
<div class="answers">
<ul class="col">
<h3>Across</h3>
{clues?.across?.map((a) => (
<li>{decodeHtmlEntity(a)}</li>
))}
</ul>
<ul class="col">
<h3>Down</h3>
{clues?.down?.map((a) => (
<li>{decodeHtmlEntity(a)}</li>
))}
</ul>
</div>
</div>
);
}
function Comp() {
const localData = localStorage.getItem("data");
const [data, setData] = React.useState({});
const [showCorrect, setShowCorrect] = React.useState(false);
const cellState = useCellState(localData && JSON.parse(localData));
console.log(cellState.grid);
React.useEffect(() => {
$.getJSON("https://www.xwordinfo.com/JSON/Data.ashx?callback=?", {
headers: {
Accept: "application/json",
mode: "no-cors"
}
}).then((d) => {
setData(d);
});
}, []);
let goodGrid = React.useMemo(() => {
let rows = {};
let row = {};
let rowCount = 1;
let rowNum = 1;
data?.grid?.forEach((d, index) => {
// console.log(d, index)
if (rowCount === data.size.rows) {
rows[rowNum] = { ...row };
row = {};
rowCount = 1;
rowNum++;
} else {
row[rowCount] = {
letter: d,
number: data.gridnums[index],
value: undefined
};
rowCount++;
}
});
return rows;
}, [data]);
React.useEffect(() => {
if (!localData) {
cellState.setAll(goodGrid);
}
}, [goodGrid]);
console.log(goodGrid);
return (
<div class="wrapper">
<div class="box">
{Object.keys(goodGrid).map((r, i) => (
<Row
row={goodGrid[r]}
rowNum={r}
cellState={cellState}
showCorrect={showCorrect}
/>
))}
</div>
<Clues
clues={data?.clues}
showCorrect={showCorrect}
setShowCorrect={setShowCorrect}
/>
</div>
);
}
function App() {
return <Comp />;
}
ReactDOM.render(App(), document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
/* body {
height: 500px;
}
#root {
height: 500px;
} */
.wrapper {
width: 100%;
display: flex;
height: 500px;
overflow: hidden;
}
.cell {
width: 24px;
height: 24px;
border: 1px solid black;
position: relative;
}
.correct {
background-color: green;
}
input.cell {
text-align: center;
text-transform: uppercase;
}
.blank {
background-color: black;
}
.cellNum {
position: absolute;
left: 2px;
font-size: 8pt;
font-family: monospace;
}
.answers {
display: flex;
width: 100%;
height: 100%;
flex: 1 1 auto;
}
.col {
overflow: scroll;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment