From 9f9236ba9bfcceaba4ca90476caf69890eb5942c Mon Sep 17 00:00:00 2001
From: lingdocs <71590811+lingdocs@users.noreply.github.com>
Date: Tue, 5 Apr 2022 00:40:55 +0500
Subject: [PATCH] towards new verb explorer form
---
package.json | 2 +-
src/components/VerbPicker.tsx | 391 +++---------------
src/components/VerbPickerBelow.tsx | 177 ++++++++
.../phrase-builder/PhraseBuilder.tsx | 35 +-
.../phrase-builder/verb-selection.ts | 108 +++++
yarn.lock | 8 +-
6 files changed, 367 insertions(+), 354 deletions(-)
create mode 100644 src/components/VerbPickerBelow.tsx
create mode 100644 src/components/phrase-builder/verb-selection.ts
diff --git a/package.json b/package.json
index eb36bc7..b1caf78 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,7 @@
"dependencies": {
"@fortawesome/fontawesome-free": "^5.15.4",
"@lingdocs/lingdocs-main": "^0.2.0",
- "@lingdocs/pashto-inflector": "^1.6.8",
+ "@lingdocs/pashto-inflector": "^1.6.9",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
diff --git a/src/components/VerbPicker.tsx b/src/components/VerbPicker.tsx
index a7b756c..80c3b51 100644
--- a/src/components/VerbPicker.tsx
+++ b/src/components/VerbPicker.tsx
@@ -1,73 +1,12 @@
-import Select from "react-select";
import {
- makeNounSelection,
- zIndexProps,
-} from "./np-picker/picker-tools";
-import {
- Types as T,
ButtonSelect,
- getVerbInfo,
} from "@lingdocs/pashto-inflector";
-import { isPerfectTense } from "../lib/phrase-building/vp-tools";
+import {
+ makeVerbSelection,
+} from "./phrase-builder/verb-selection";
import EntrySelect from "./EntrySelect";
-// import { useState } from "react";
-const tenseOptions: { label: string | JSX.Element, value: VerbTense }[] = [{
- label:
present
,
- value: "presentVerb",
-}, {
- label: subjunctive
,
- value: "subjunctiveVerb",
-}, {
- label: imperf. future
,
- value: "imperfectiveFuture",
-}, {
- label: perf. future
,
- value: "perfectiveFuture",
-}, {
- label: continuous past
,
- value: "imperfectivePast",
-}, {
- label: simple past
,
- value: "perfectivePast",
-}, {
- label: habitual cont. past.
,
- value: "habitualImperfectivePast",
-}, {
- label: habitual simp. past.
,
- value: "habitualPerfectivePast",
-}];
-
-const perfectTenseOptions: { label: string | JSX.Element, value: PerfectTense }[] = [{
- label: "Present Perfect",
- value: "present perfect",
-}, {
- label: "Habitual Perfect",
- value: "habitual perfect",
-}, {
- label: "Subjunctive Perfect",
- value: "subjunctive perfect",
-}, {
- label: "Future Perfect",
- value: "future perfect",
-}, {
- label: "Past Perfect",
- value: "past perfect",
-}, {
- label: `"Would Be" Perfect`,
- value: "wouldBe perfect",
-}, {
- label: "Past Subjunctive Perfect",
- value: "pastSubjunctive perfect",
-}];
-
-// type Filters = {
-// stative: boolean,
-// dynamic: boolean,
-// transitive: boolean,
-// intransitive: boolean,
-// grammaticallyTransitive: boolean,
-// }
+// TODO: dark on past tense selecitons
function VerbPicker({ onChange, subject, changeSubject, verb, verbs }: {
verbs: VerbEntry[],
@@ -90,65 +29,6 @@ function VerbPicker({ onChange, subject, changeSubject, verb, verbs }: {
}
onChange(makeVerbSelection(v, changeSubject, verb));
}
- function onTenseSelect(o: { value: VerbTense | PerfectTense } | null) {
- const value = o?.value ? o.value : undefined;
- if (verb && value) {
- if (isPerfectTense(value)) {
- onChange({
- ...verb,
- tense: value,
- tenseCategory: "perfect",
- });
- } else {
- onChange({
- ...verb,
- tense: value,
- tenseCategory: verb.tenseCategory === "perfect" ? "basic" : verb.tenseCategory,
- });
- }
- }
- }
- function moveTense(dir: "forward" | "back") {
- if (!verb) return;
- return () => {
- const tenses = verb.tenseCategory === "perfect" ? perfectTenseOptions : tenseOptions;
- const currIndex = tenses.findIndex(tn => tn.value === verb.tense)
- if (currIndex === -1) {
- console.error("error moving tense", dir);
- return;
- }
- const newIndex = dir === "forward"
- ? ((currIndex + 1) % tenses.length)
- : (currIndex === 0 ? (tenses.length - 1) : (currIndex - 1))
- const newTense = tenses[newIndex];
- onTenseSelect(newTense);
- };
- }
- function onPosNegSelect(value: string) {
- if (verb) {
- onChange({
- ...verb,
- negative: value === "true",
- });
- }
- }
- function onTenseCategorySelect(value: "basic" | "modal" | "perfect") {
- if (verb) {
- if (value === "perfect") {
- onChange({
- ...verb,
- tenseCategory: value,
- tense: isPerfectTense(verb.tense) ? verb.tense : "present perfect",
- });
- } else {
- onChange({
- ...verb,
- tenseCategory: value,
- tense: isPerfectTense(verb.tense) ? "presentVerb" : verb.tense,
- });
- }
- }
- }
function onVoiceSelect(value: "active" | "passive") {
if (verb && verb.changeVoice) {
if (value === "passive" && (typeof verb.object === "object")) {
@@ -173,218 +53,63 @@ function VerbPicker({ onChange, subject, changeSubject, verb, verbs }: {
onChange(verb.changeStatDyn(c));
}
}
- const tOptions = (verb?.tenseCategory === "perfect") ? perfectTenseOptions : tenseOptions;
- return
-
Verb:
-
- {/*
;
}
-function makeVerbSelection(verb: VerbEntry, changeSubject: (s: NPSelection | undefined) => void, oldVerbSelection?: VerbSelection): VerbSelection {
- const info = getVerbInfo(verb.entry, verb.complement);
- function getTransObjFromOldVerbSelection() {
- if (
- !oldVerbSelection ||
- oldVerbSelection.object === "none" ||
- typeof oldVerbSelection.object === "number" ||
- oldVerbSelection.isCompound === "dynamic" ||
- (oldVerbSelection.object?.type === "noun" && oldVerbSelection.object.dynamicComplement)
- ) return undefined;
- return oldVerbSelection.object;
- }
- const transitivity: T.Transitivity = "grammaticallyTransitive" in info
- ? "transitive"
- : info.transitivity;
- const object = (transitivity === "grammatically transitive")
- ? T.Person.ThirdPlurMale
- : (info.type === "dynamic compound" && oldVerbSelection?.voice !== "passive")
- ? makeNounSelection(info.objComplement.entry as NounEntry, true)
- : (transitivity === "transitive" && oldVerbSelection?.voice !== "passive")
- ? getTransObjFromOldVerbSelection()
- : "none";
- if (oldVerbSelection?.voice === "passive" && info.type === "dynamic compound") {
- changeSubject(makeNounSelection(info.objComplement.entry as NounEntry, true));
- }
- const isCompound = ("stative" in info || info.type === "stative compound")
- ? "stative"
- : info.type === "dynamic compound"
- ? "dynamic"
- : false;
- // TODO: here and below in the changeStatDyn function ... allow for entries with complement
- const dynAuxVerb: VerbEntry | undefined = isCompound !== "dynamic"
- ? undefined
- : info.type === "dynamic compound"
- ? { entry: info.auxVerb } as VerbEntry
- : "dynamic" in info
- ? { entry: info.dynamic.auxVerb } as VerbEntry
- : undefined;
- const tenseSelection = ((): { tenseCategory: "perfect", tense: PerfectTense } | {
- tenseCategory: "basic" | "modal",
- tense: VerbTense,
- } => {
- if (!oldVerbSelection) {
- return { tense: "presentVerb", tenseCategory: "basic" };
- }
- if (oldVerbSelection.tenseCategory === "modal") {
- return { tenseCategory: "modal", tense: isPerfectTense(oldVerbSelection.tense) ? "presentVerb" : oldVerbSelection.tense };
- }
- if (oldVerbSelection.tenseCategory === "basic") {
- return { tenseCategory: "basic", tense: isPerfectTense(oldVerbSelection.tense) ? "presentVerb" : oldVerbSelection.tense };
- }
- return { tenseCategory: "perfect", tense: isPerfectTense(oldVerbSelection.tense) ? oldVerbSelection.tense : "present perfect" };
- })();
- return {
- type: "verb",
- verb: verb,
- dynAuxVerb,
- ...tenseSelection,
- object,
- transitivity,
- isCompound,
- voice: transitivity === "transitive"
- ? (oldVerbSelection?.voice || "active")
- : "active",
- negative: oldVerbSelection ? oldVerbSelection.negative : false,
- ...("grammaticallyTransitive" in info) ? {
- changeTransitivity: function(t) {
- return {
- ...this,
- transitivity: t,
- object: t === "grammatically transitive" ? T.Person.ThirdPlurMale : undefined,
- };
- },
- } : {},
- ...("stative" in info) ? {
- changeStatDyn: function(c) {
- return {
- ...this,
- isCompound: c,
- object: c === "dynamic"
- ? makeNounSelection(info.dynamic.objComplement.entry as NounEntry, true)
- : undefined,
- dynAuxVerb: c === "dynamic"
- ? { entry: info.dynamic.auxVerb } as VerbEntry
- : undefined,
- };
- }
- } : {},
- ...(transitivity === "transitive") ? {
- changeVoice: function(v, s) {
- return {
- ...this,
- voice: v,
- object: v === "active" ? s : "none",
- };
- },
- } : {},
- };
-}
export default VerbPicker;
\ No newline at end of file
diff --git a/src/components/VerbPickerBelow.tsx b/src/components/VerbPickerBelow.tsx
new file mode 100644
index 0000000..82b2acb
--- /dev/null
+++ b/src/components/VerbPickerBelow.tsx
@@ -0,0 +1,177 @@
+import Select from "react-select";
+import {
+ zIndexProps,
+} from "./np-picker/picker-tools";
+import {
+ ButtonSelect,
+} from "@lingdocs/pashto-inflector";
+import { isPerfectTense } from "../lib/phrase-building/vp-tools";
+
+const tenseOptions: { label: string | JSX.Element, value: VerbTense }[] = [{
+ label: present
,
+ value: "presentVerb",
+}, {
+ label: subjunctive
,
+ value: "subjunctiveVerb",
+}, {
+ label: imperf. future
,
+ value: "imperfectiveFuture",
+}, {
+ label: perf. future
,
+ value: "perfectiveFuture",
+}, {
+ label: continuous past
,
+ value: "imperfectivePast",
+}, {
+ label: simple past
,
+ value: "perfectivePast",
+}, {
+ label: habitual cont. past.
,
+ value: "habitualImperfectivePast",
+}, {
+ label: habitual simp. past.
,
+ value: "habitualPerfectivePast",
+}];
+
+const perfectTenseOptions: { label: string | JSX.Element, value: PerfectTense }[] = [{
+ label: "Present Perfect",
+ value: "present perfect",
+}, {
+ label: "Habitual Perfect",
+ value: "habitual perfect",
+}, {
+ label: "Subjunctive Perfect",
+ value: "subjunctive perfect",
+}, {
+ label: "Future Perfect",
+ value: "future perfect",
+}, {
+ label: "Past Perfect",
+ value: "past perfect",
+}, {
+ label: `"Would Be" Perfect`,
+ value: "wouldBe perfect",
+}, {
+ label: "Past Subjunctive Perfect",
+ value: "pastSubjunctive perfect",
+}];
+
+function VerbPickerBelow({ onChange, verb }: {
+ verbs: VerbEntry[],
+ verb: VerbSelection | undefined,
+ onChange: (p: VerbSelection | undefined) => void,
+}) {
+ function onTenseSelect(o: { value: VerbTense | PerfectTense } | null) {
+ const value = o?.value ? o.value : undefined;
+ if (verb && value) {
+ if (isPerfectTense(value)) {
+ onChange({
+ ...verb,
+ tense: value,
+ tenseCategory: "perfect",
+ });
+ } else {
+ onChange({
+ ...verb,
+ tense: value,
+ tenseCategory: verb.tenseCategory === "perfect" ? "basic" : verb.tenseCategory,
+ });
+ }
+ }
+ }
+ function moveTense(dir: "forward" | "back") {
+ if (!verb) return;
+ return () => {
+ const tenses = verb.tenseCategory === "perfect" ? perfectTenseOptions : tenseOptions;
+ const currIndex = tenses.findIndex(tn => tn.value === verb.tense)
+ if (currIndex === -1) {
+ console.error("error moving tense", dir);
+ return;
+ }
+ const newIndex = dir === "forward"
+ ? ((currIndex + 1) % tenses.length)
+ : (currIndex === 0 ? (tenses.length - 1) : (currIndex - 1))
+ const newTense = tenses[newIndex];
+ onTenseSelect(newTense);
+ };
+ }
+ function onPosNegSelect(value: string) {
+ if (verb) {
+ onChange({
+ ...verb,
+ negative: value === "true",
+ });
+ }
+ }
+ function onTenseCategorySelect(value: "basic" | "modal" | "perfect") {
+ if (verb) {
+ if (value === "perfect") {
+ onChange({
+ ...verb,
+ tenseCategory: value,
+ tense: isPerfectTense(verb.tense) ? verb.tense : "present perfect",
+ });
+ } else {
+ onChange({
+ ...verb,
+ tenseCategory: value,
+ tense: isPerfectTense(verb.tense) ? "presentVerb" : verb.tense,
+ });
+ }
+ }
+ }
+ const tOptions = (verb?.tenseCategory === "perfect") ? perfectTenseOptions : tenseOptions;
+ return
+ {verb &&
+
+
}
+
+
Tense:
+
o.value === verb.tense))}
+ onChange={onTenseSelect}
+ className="mb-2"
+ options={tOptions}
+ {...zIndexProps}
+ />
+ {verb && }
+
+
;
+}
+
+export default VerbPickerBelow;
\ No newline at end of file
diff --git a/src/components/phrase-builder/PhraseBuilder.tsx b/src/components/phrase-builder/PhraseBuilder.tsx
index 3789962..7452a56 100644
--- a/src/components/phrase-builder/PhraseBuilder.tsx
+++ b/src/components/phrase-builder/PhraseBuilder.tsx
@@ -1,6 +1,7 @@
import { useState } from "react";
import NPPicker from "../np-picker/NPPicker";
import VerbPicker from "../VerbPicker";
+import VerbPickerBelow from "../VerbPickerBelow";
import VPDisplay from "./VPDisplay";
import { verbs } from "../../words/words";
import { renderVP } from "../../lib/phrase-building";
@@ -47,13 +48,20 @@ export function PhraseBuilder() {
{kingEmoji} =
king of phrase
{servantEmoji} =
servant of phrase
+ handleSubjectChange(s, true)}
+ onChange={setVerb}
+ />
{(verb && (typeof verb.object === "object") && (verb.isCompound !== "dynamic")) &&
- }
+
+
+ {/*
{` `}
*/}
+
}
Subject {showRole(VPRendered, "subject")}
@@ -74,17 +82,12 @@ export function PhraseBuilder() {
onChange={handleObjectChange}
/>}
}
-
-
Verb
-
handleSubjectChange(s, true)}
- onChange={setVerb}
- />
-
+
{verbPhrase &&
}
diff --git a/src/components/phrase-builder/verb-selection.ts b/src/components/phrase-builder/verb-selection.ts
new file mode 100644
index 0000000..730025e
--- /dev/null
+++ b/src/components/phrase-builder/verb-selection.ts
@@ -0,0 +1,108 @@
+import {
+ makeNounSelection,
+} from "../np-picker/picker-tools";
+import {
+ getVerbInfo,
+ Types as T,
+} from "@lingdocs/pashto-inflector";
+import { isPerfectTense } from "../../lib/phrase-building/vp-tools";
+
+export function makeVerbSelection(verb: VerbEntry, changeSubject: (s: NPSelection | undefined) => void, oldVerbSelection?: VerbSelection): VerbSelection {
+ const info = getVerbInfo(verb.entry, verb.complement);
+ function getTransObjFromOldVerbSelection() {
+ if (
+ !oldVerbSelection ||
+ oldVerbSelection.object === "none" ||
+ typeof oldVerbSelection.object === "number" ||
+ oldVerbSelection.isCompound === "dynamic" ||
+ (oldVerbSelection.object?.type === "noun" && oldVerbSelection.object.dynamicComplement)
+ ) return undefined;
+ return oldVerbSelection.object;
+ }
+ const transitivity: T.Transitivity = "grammaticallyTransitive" in info
+ ? "transitive"
+ : info.transitivity;
+ const object = (transitivity === "grammatically transitive")
+ ? T.Person.ThirdPlurMale
+ : (info.type === "dynamic compound" && oldVerbSelection?.voice !== "passive")
+ ? makeNounSelection(info.objComplement.entry as NounEntry, true)
+ : (transitivity === "transitive" && oldVerbSelection?.voice !== "passive")
+ ? getTransObjFromOldVerbSelection()
+ : "none";
+ if (oldVerbSelection?.voice === "passive" && info.type === "dynamic compound") {
+ changeSubject(makeNounSelection(info.objComplement.entry as NounEntry, true));
+ }
+ const isCompound = ("stative" in info || info.type === "stative compound")
+ ? "stative"
+ : info.type === "dynamic compound"
+ ? "dynamic"
+ : false;
+ // TODO: here and below in the changeStatDyn function ... allow for entries with complement
+ const dynAuxVerb: VerbEntry | undefined = isCompound !== "dynamic"
+ ? undefined
+ : info.type === "dynamic compound"
+ ? { entry: info.auxVerb } as VerbEntry
+ : "dynamic" in info
+ ? { entry: info.dynamic.auxVerb } as VerbEntry
+ : undefined;
+ const tenseSelection = ((): { tenseCategory: "perfect", tense: PerfectTense } | {
+ tenseCategory: "basic" | "modal",
+ tense: VerbTense,
+ } => {
+ if (!oldVerbSelection) {
+ return { tense: "presentVerb", tenseCategory: "basic" };
+ }
+ if (oldVerbSelection.tenseCategory === "modal") {
+ return { tenseCategory: "modal", tense: isPerfectTense(oldVerbSelection.tense) ? "presentVerb" : oldVerbSelection.tense };
+ }
+ if (oldVerbSelection.tenseCategory === "basic") {
+ return { tenseCategory: "basic", tense: isPerfectTense(oldVerbSelection.tense) ? "presentVerb" : oldVerbSelection.tense };
+ }
+ return { tenseCategory: "perfect", tense: isPerfectTense(oldVerbSelection.tense) ? oldVerbSelection.tense : "present perfect" };
+ })();
+ return {
+ type: "verb",
+ verb: verb,
+ dynAuxVerb,
+ ...tenseSelection,
+ object,
+ transitivity,
+ isCompound,
+ voice: transitivity === "transitive"
+ ? (oldVerbSelection?.voice || "active")
+ : "active",
+ negative: oldVerbSelection ? oldVerbSelection.negative : false,
+ ...("grammaticallyTransitive" in info) ? {
+ changeTransitivity: function(t) {
+ return {
+ ...this,
+ transitivity: t,
+ object: t === "grammatically transitive" ? T.Person.ThirdPlurMale : undefined,
+ };
+ },
+ } : {},
+ ...("stative" in info) ? {
+ changeStatDyn: function(c) {
+ return {
+ ...this,
+ isCompound: c,
+ object: c === "dynamic"
+ ? makeNounSelection(info.dynamic.objComplement.entry as NounEntry, true)
+ : undefined,
+ dynAuxVerb: c === "dynamic"
+ ? { entry: info.dynamic.auxVerb } as VerbEntry
+ : undefined,
+ };
+ }
+ } : {},
+ ...(transitivity === "transitive") ? {
+ changeVoice: function(v, s) {
+ return {
+ ...this,
+ voice: v,
+ object: v === "active" ? s : "none",
+ };
+ },
+ } : {},
+ };
+}
diff --git a/yarn.lock b/yarn.lock
index 175da32..420af2c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1684,10 +1684,10 @@
pbf "^3.2.1"
rambda "^6.7.0"
-"@lingdocs/pashto-inflector@^1.6.8":
- version "1.6.8"
- resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-1.6.8.tgz#adc94c84c49cc067e26fb3066fae2a13b9d25d03"
- integrity sha512-BGzMP0URWm6fEGdUUX653oImSMEkn11S/3vxeQILrQDCUNjGpNPQlORF27OlzCs8+n9lDBMDQHVjfhBlAZFN4w==
+"@lingdocs/pashto-inflector@^1.6.9":
+ version "1.6.9"
+ resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-1.6.9.tgz#cd66b8afe1c55ce609ba25952984cd5c329355ac"
+ integrity sha512-ipssrtenaDr9k/VFz6WAxZ/spVb62IFgxczSVsd8Zc/fdIqzy9UKV4R4efJhBp2d7h5QadqBkfEk81PUZu48UQ==
dependencies:
classnames "^2.2.6"
pbf "^3.2.1"