pronoun picker tool

This commit is contained in:
lingdocs 2021-11-03 20:09:42 -04:00
parent d71064ef43
commit baf693b6da
9 changed files with 220 additions and 10 deletions

View File

@ -5,7 +5,7 @@
"dependencies": {
"@fortawesome/fontawesome-free": "^5.15.4",
"@lingdocs/lingdocs-main": "^0.2.0",
"@lingdocs/pashto-inflector": "^1.3.9",
"@lingdocs/pashto-inflector": "^1.4.4",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",

View File

@ -0,0 +1,137 @@
import {
Types as T,
ButtonSelect,
} from "@lingdocs/pashto-inflector";
import useStickyState from "../../useStickyState";
const gColors = {
masc: "LightSkyBlue",
fem: "pink",
};
const labels = {
persons: [
["1st", "1st pl."],
["2nd", "2nd pl."],
["3rd", "3rd pl."],
],
e: [
["I", "We"],
["You", "You pl."],
[{ masc: "He/It", fem: "She/It"}, "They"],
],
p: {
far: [
["زه", "مونږ"],
["ته", "تاسو"],
["هغه", "هغوي"],
],
near: [
["زه", "مونږ"],
["ته", "تاسو"],
[{ masc: "دی", fem: "دا" }, "دوي"],
],
},
};
type PickerState = { row: number, col: number, gender: T.Gender };
function personToPickerState(person: T.Person): PickerState {
const col = person > 5 ? 1 : 0;
const row = Math.floor((person > 5 ? (person - 6) : person) / 2);
const gender: T.Gender = (person % 2) ? "fem" : "masc";
return { col, row, gender };
}
function pickerStateToPerson(s: PickerState): T.Person {
return (s.row * 2)
+ (s.gender === "masc" ? 0 : 1)
+ (6 * s.col);
}
function PronounPicker({ onChange, pronoun }: { pronoun: Pronoun, onChange: (p: Pronoun) => void }) {
const [display, setDisplay] = useStickyState<"persons" | "p" | "e">("persons", "prounoun-picker-display");
const p = personToPickerState(pronoun.person);
function handleClick(row: number, col: number) {
onChange({
...pronoun,
person: pickerStateToPerson({
...p,
row,
col,
}),
});
}
function handleGenderChange(gender: T.Gender) {
onChange({
...pronoun,
person: pickerStateToPerson({
...p,
gender,
}),
});
}
function handlePronounTypeChange(pronounType: "far" | "near") {
onChange({
...pronoun,
pronounType,
});
}
function handleDisplayChange() {
const newPerson = display === "persons"
? "p"
: display === "p"
? "e"
: "persons";
setDisplay(newPerson);
}
const prs = labels[display];
const pSpec = "near" in prs ? prs[pronoun.pronounType] : prs;
return <div>
<div className="d-flex flex-row justify-content-around mb-3">
<ButtonSelect
xSmall
options={[
{ label: "Far", value: "far" },
{ label: "Near", value: "near" },
]}
value={pronoun.pronounType}
handleChange={(g) => handlePronounTypeChange(g as "far" | "near")}
/>
<button className="btn btn-sm btn-outline" onClick={handleDisplayChange}>{display === "persons" ? "#" : display === "p" ? "PS" : "EN"}</button>
</div>
<table className="table table-bordered" style={{ textAlign: "center", minWidth: "200px", tableLayout: "fixed" }}>
<tbody>
{pSpec.map((rw, i) => (
<tr>
{rw.map((r, j) => {
const active = (p.row === i && p.col === j)
return <td
onClick={() => handleClick(i, j)}
className={active ? "table-active" : ""}
style={active ? { backgroundColor: gColors[p.gender] } : {}}
>
{typeof r === "string" ? r : r[p.gender]}
</td>;
})}
</tr>
))}
</tbody>
</table>
<div className="text-center">
<ButtonSelect
options={[
{ label: "Masc.", value: "masc", color: gColors.masc },
{ label: "Fem.", value: "fem", color: gColors.fem },
]}
value={p.gender}
handleChange={(g) => handleGenderChange(g as T.Gender)}
/>
</div>
</div>;
};
export default PronounPicker;

View File

@ -3,6 +3,18 @@ title: Equative Explorer 🌎
---
import EquativeExplorer from "../../components/equative-explorer/EquativeExplorer";
import PronounPicker from "../../components/np-picker/PronounPicker";
import { useState } from "react";
export function PDem() {
const [pronoun, setPronoun] = useState({ type: "pronoun", pronounType: "far", person: 11 });
return <div style={{ maxWidth: "200px" }}>
<PronounPicker pronoun={pronoun} onChange={setPronoun} />
<pre>{JSON.stringify(pronoun, null, " ")}</pre>
</div>
}
<PDem />
You can use this tool to explore how to make different equative sentences. Everything that comes out of this will be **gramatically correct**, but the sentences might not always make sense! 🤪

View File

@ -78,6 +78,9 @@ import * as typingIssues from "!babel-loader!@lingdocs/mdx-loader!./writing/typi
// @ts-ignore
import * as games from "!babel-loader!@lingdocs/mdx-loader!./games.mdx";
// @ts-ignore
import * as pronounPicker from "!babel-loader!@lingdocs/mdx-loader!./practice-tools/pronoun-picker.mdx";
const contentTree = [
{
import: intro,
@ -245,6 +248,16 @@ const contentTree = [
import: games,
slug: "games",
},
{
heading: "Practice Tools 🔧",
subdirectory: "practice-tools",
chapters: [
{
import: pronounPicker,
slug: "pronoun-picker",
},
],
},
];
export const content = contentTree.map((item) => {

View File

@ -0,0 +1,48 @@
---
title: Pronoun Picker
---
import PronounPicker from "../../components/np-picker/PronounPicker";
import {
defaultTextOptions as opts,
InlinePs,
} from "@lingdocs/pashto-inflector";
import { useState } from "react";
export function randomP(p) {
let newP = 0;
do {
newP = Math.floor(Math.random() * 12);
} while (newP === p);
return newP;
}
export function RPicker() {
const [pronoun, setPronoun] = useState({ type: "pronoun", pronounType: "far", person: randomP() });
function handleRandom() {
const person = randomP(pronoun.person);
setPronoun({
...pronoun,
person,
});
}
return <div className="text-center">
<div className="my-4" style={{ maxWidth: "375px", margin: "0 auto" }}>
<PronounPicker pronoun={pronoun} onChange={setPronoun} />
</div>
<button className="btn btn-lg btn-primary mt-2">
<i class="fas fa-random" onClick={handleRandom} />
</button>
</div>;
}
Use this pronoun picker to help you drill different sentences. Choose different pronouns to drill a friend, or press the <i class="fas fa-random"></i> button to get a random selection.
<div className="mt-4">
<RPicker />
</div>
<details className="mt-4">
<summary>Show Second Picker</summary>
<RPicker />
</details>

View File

@ -45,6 +45,7 @@ type Compliment = {
type Participle = {
type: "participle",
entry: VerbEntry,
np?: NounPhrase,
}
type Pronoun = {

View File

@ -1,10 +1,9 @@
import { useEffect, useState } from "react";
export default function useStickyState<T>(defaultValue: T, key: string): {
export default function useStickyState<T>(defaultValue: T, key: string): [
value: T,
setValue: React.Dispatch<React.SetStateAction<T>>,
} {
] {
const [value, setValue] = useState<T>(() => {
const stickyValue = window.localStorage.getItem(key);
if (stickyValue === null) return defaultValue;
@ -20,5 +19,5 @@ export default function useStickyState<T>(defaultValue: T, key: string): {
window.localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return {value, setValue};
return [value, setValue];
}

View File

@ -19,7 +19,7 @@ const UserContext = createContext<
// TODO: persisting user in local state
function UserProvider({ children }: any) {
const {value, setValue} = useStickyState<AT.LingdocsUser | undefined>(
const [value, setValue] = useStickyState<AT.LingdocsUser | undefined>(
undefined,
"saved-user",
);

View File

@ -1684,10 +1684,10 @@
pbf "^3.2.1"
rambda "^6.7.0"
"@lingdocs/pashto-inflector@^1.3.5":
version "1.3.5"
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-1.3.5.tgz#cfc311462c686e5591f12ee68b333a2ec479f428"
integrity sha512-Asxu773Z9+0Gxi8wkSD6x3JYcSeJmXqgoHQu1Hvph1oOAac3t8Bn0uXC/OGO5p1leilEHePJT+hkMFmURTArcw==
"@lingdocs/pashto-inflector@^1.4.4":
version "1.4.4"
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-1.4.4.tgz#5015bf1e4abd913bdb2cbcc08a89ab64a7194d9e"
integrity sha512-RGf3AZFpy4JWzjWLeeGNLvy1PsDljRcDF4mQIqMPrFeakkuT4h3/exbGAANehNWGt9hm6LbPvXyXQmxe7SWaXg==
dependencies:
classnames "^2.2.6"
pbf "^3.2.1"