refactoring to allow for dictionary lookup in phrase builder
This commit is contained in:
parent
8191b48f05
commit
759df4811e
|
@ -13,7 +13,7 @@ function EntrySelect<E extends T.DictionaryEntry | VerbEntry>(props: ({
|
||||||
entries: E[]
|
entries: E[]
|
||||||
} | {
|
} | {
|
||||||
searchF: (search: string) => E[],
|
searchF: (search: string) => E[],
|
||||||
getByTs: (ts: number) => E,
|
getByTs: (ts: number) => E | undefined,
|
||||||
}) & {
|
}) & {
|
||||||
value: E | undefined,
|
value: E | undefined,
|
||||||
onChange: (value: E | undefined) => void,
|
onChange: (value: E | undefined) => void,
|
||||||
|
|
|
@ -6,83 +6,93 @@ import {
|
||||||
InlinePs,
|
InlinePs,
|
||||||
Types as T,
|
Types as T,
|
||||||
} from "@lingdocs/pashto-inflector";
|
} from "@lingdocs/pashto-inflector";
|
||||||
import { useState } from "react";
|
// import { useState } from "react";
|
||||||
import { isFemNounEntry, isPattern1Entry, isPattern2Entry, isPattern3Entry, isPattern4Entry, isPattern5Entry, isPattern6FemEntry } from "../../lib/type-predicates";
|
// import { isFemNounEntry, isPattern1Entry, isPattern2Entry, isPattern3Entry, isPattern4Entry, isPattern5Entry, isPattern6FemEntry } from "../../lib/type-predicates";
|
||||||
import EntrySelect from "../EntrySelect";
|
import EntrySelect from "../EntrySelect";
|
||||||
|
|
||||||
const filterOptions = [
|
// const filterOptions = [
|
||||||
{
|
// {
|
||||||
label: "1",
|
// label: "1",
|
||||||
value: "1",
|
// value: "1",
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
label: "2",
|
// label: "2",
|
||||||
value: "2",
|
// value: "2",
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
label: "3",
|
// label: "3",
|
||||||
value: "3",
|
// value: "3",
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
label: "4",
|
// label: "4",
|
||||||
value: "4",
|
// value: "4",
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
label: "5",
|
// label: "5",
|
||||||
value: "5",
|
// value: "5",
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
label: "6",
|
// label: "6",
|
||||||
value: "6",
|
// value: "6",
|
||||||
},
|
// },
|
||||||
];
|
// ];
|
||||||
|
|
||||||
type FilterPattern = "1" | "2" | "3" | "4" | "5" | "6";
|
// type FilterPattern = "1" | "2" | "3" | "4" | "5" | "6";
|
||||||
|
|
||||||
function nounFilter(p: FilterPattern | undefined) {
|
// function nounFilter(p: FilterPattern | undefined) {
|
||||||
return p === undefined
|
// return p === undefined
|
||||||
? () => true
|
// ? () => true
|
||||||
: (p === "1")
|
// : (p === "1")
|
||||||
? isPattern1Entry
|
// ? isPattern1Entry
|
||||||
: (p === "2")
|
// : (p === "2")
|
||||||
? isPattern2Entry
|
// ? isPattern2Entry
|
||||||
: (p === "3")
|
// : (p === "3")
|
||||||
? isPattern3Entry
|
// ? isPattern3Entry
|
||||||
: (p === "4")
|
// : (p === "4")
|
||||||
? isPattern4Entry
|
// ? isPattern4Entry
|
||||||
: (p === "5")
|
// : (p === "5")
|
||||||
? isPattern5Entry
|
// ? isPattern5Entry
|
||||||
: (p === "6")
|
// : (p === "6")
|
||||||
? (n: NounEntry) => (isFemNounEntry(n) && isPattern6FemEntry(n))
|
// ? (n: NounEntry) => (isFemNounEntry(n) && isPattern6FemEntry(n))
|
||||||
: () => true;
|
// : () => true;
|
||||||
}
|
// }
|
||||||
|
|
||||||
function NPNounPicker({ onChange, noun, nouns, clearButton, opts }: { nouns: NounEntry[], noun: NounSelection | undefined, onChange: (p: NounSelection | undefined) => void, clearButton?: JSX.Element, opts: T.TextOptions }) {
|
function NPNounPicker(props: ({
|
||||||
const [patternFilter, setPatternFilter] = useState<FilterPattern | undefined>(undefined);
|
nouns: NounEntry[],
|
||||||
const [showFilter, setShowFilter] = useState<boolean>(false)
|
} | {
|
||||||
const nounsFiltered = nouns
|
nouns: (s: string) => NounEntry[],
|
||||||
.filter(nounFilter(patternFilter))
|
getNounByTs: (ts: number) => NounEntry | undefined;
|
||||||
.sort((a, b) => (a.p.localeCompare(b.p, "af-PS")));
|
}) & {
|
||||||
|
noun: NounSelection | undefined,
|
||||||
|
onChange: (p: NounSelection | undefined) => void,
|
||||||
|
clearButton?: JSX.Element,
|
||||||
|
opts: T.TextOptions,
|
||||||
|
}) {
|
||||||
|
// const [patternFilter, setPatternFilter] = useState<FilterPattern | undefined>(undefined);
|
||||||
|
// const [showFilter, setShowFilter] = useState<boolean>(false)
|
||||||
|
// const nounsFiltered = props.nouns
|
||||||
|
// .filter(nounFilter(patternFilter))
|
||||||
|
// .sort((a, b) => (a.p.localeCompare(b.p, "af-PS")));
|
||||||
function onEntrySelect(entry: NounEntry | undefined) {
|
function onEntrySelect(entry: NounEntry | undefined) {
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
return onChange(undefined);
|
return props.onChange(undefined);
|
||||||
}
|
}
|
||||||
onChange(makeNounSelection(entry));
|
props.onChange(makeNounSelection(entry));
|
||||||
}
|
|
||||||
function handleFilterClose() {
|
|
||||||
setPatternFilter(undefined);
|
|
||||||
setShowFilter(false);
|
|
||||||
}
|
}
|
||||||
|
// function handleFilterClose() {
|
||||||
|
// setPatternFilter(undefined);
|
||||||
|
// setShowFilter(false);
|
||||||
|
// }
|
||||||
return <div style={{ maxWidth: "225px", minWidth: "125px" }}>
|
return <div style={{ maxWidth: "225px", minWidth: "125px" }}>
|
||||||
<div className="d-flex flex-row justify-content-between">
|
<div className="d-flex flex-row justify-content-left">
|
||||||
{clearButton}
|
{props.clearButton}
|
||||||
{(!showFilter && !(noun?.dynamicComplement)) && <div className="text-right">
|
{/* {(!showFilter && !(noun?.dynamicComplement)) && <div className="text-right">
|
||||||
<button className="btn btn-sm btn-light mb-2 text-small" onClick={() => setShowFilter(true)}>
|
<button className="btn btn-sm btn-light mb-2 text-small" onClick={() => setShowFilter(true)}>
|
||||||
<i className="fas fa-filter fa-xs" />
|
<i className="fas fa-filter fa-xs" />
|
||||||
</button>
|
</button>
|
||||||
</div>}
|
</div>} */}
|
||||||
</div>
|
</div>
|
||||||
{showFilter && <div className="mb-2 text-center">
|
{/* {showFilter && <div className="mb-2 text-center">
|
||||||
<div className="d-flex flex-row justify-content-between">
|
<div className="d-flex flex-row justify-content-between">
|
||||||
<div className="text-small mb-1">Filter by inflection pattern</div>
|
<div className="text-small mb-1">Filter by inflection pattern</div>
|
||||||
<div className="clickable" onClick={handleFilterClose}>X</div>
|
<div className="clickable" onClick={handleFilterClose}>X</div>
|
||||||
|
@ -94,54 +104,59 @@ function NPNounPicker({ onChange, noun, nouns, clearButton, opts }: { nouns: Nou
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
handleChange={setPatternFilter}
|
handleChange={setPatternFilter}
|
||||||
/>
|
/>
|
||||||
</div>}
|
</div>} */}
|
||||||
{!(noun && noun.dynamicComplement) ? <div>
|
{!(props.noun && props.noun.dynamicComplement) ? <div>
|
||||||
<EntrySelect
|
<EntrySelect
|
||||||
value={noun?.entry}
|
value={props.noun?.entry}
|
||||||
entries={nounsFiltered}
|
{..."getNounByTs" in props ? {
|
||||||
|
getByTs: props.getNounByTs,
|
||||||
|
searchF: props.nouns
|
||||||
|
} : {
|
||||||
|
entries: props.nouns,
|
||||||
|
}}
|
||||||
onChange={onEntrySelect}
|
onChange={onEntrySelect}
|
||||||
name="Noun"
|
name="Noun"
|
||||||
opts={opts}
|
opts={props.opts}
|
||||||
/>
|
/>
|
||||||
</div> : <div>
|
</div> : <div>
|
||||||
{noun && <div>
|
{props.noun && <div>
|
||||||
<div className="mb-2">Included in Dyn. Compound:</div>
|
<div className="mb-2">Included in Dyn. Compound:</div>
|
||||||
<div className="mb-3 text-center">
|
<div className="mb-3 text-center">
|
||||||
<InlinePs opts={opts}>
|
<InlinePs opts={props.opts}>
|
||||||
{{ p: noun.entry.p, f: noun.entry.f }}
|
{{ p: props.noun.entry.p, f: props.noun.entry.f }}
|
||||||
</InlinePs>
|
</InlinePs>
|
||||||
<div className="text-muted">{noun.entry.e}</div>
|
<div className="text-muted">{props.noun.entry.e}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>}
|
</div>}
|
||||||
</div>}
|
</div>}
|
||||||
{noun && <div className="my-2 d-flex flex-row justify-content-around align-items-center">
|
{props.noun && <div className="my-2 d-flex flex-row justify-content-around align-items-center">
|
||||||
<div>
|
<div>
|
||||||
{noun.changeGender ? <ButtonSelect
|
{props.noun.changeGender ? <ButtonSelect
|
||||||
small
|
small
|
||||||
options={[
|
options={[
|
||||||
{ label: "Masc", value: "masc" },
|
{ label: "Masc", value: "masc" },
|
||||||
{ label: "Fem", value: "fem" },
|
{ label: "Fem", value: "fem" },
|
||||||
]}
|
]}
|
||||||
value={noun.gender}
|
value={props.noun.gender}
|
||||||
handleChange={(g) => {
|
handleChange={(g) => {
|
||||||
if (!noun.changeGender) return;
|
if (!props.noun || !props.noun.changeGender) return;
|
||||||
onChange(noun.changeGender(g));
|
props.onChange(props.noun.changeGender(g));
|
||||||
}}
|
}}
|
||||||
/> : noun.gender === "masc" ? "Masc." : "Fem."}
|
/> : props.noun.gender === "masc" ? "Masc." : "Fem."}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{noun.changeNumber ? <ButtonSelect
|
{props.noun.changeNumber ? <ButtonSelect
|
||||||
small
|
small
|
||||||
options={[
|
options={[
|
||||||
{ label: "Sing.", value: "singular" },
|
{ label: "Sing.", value: "singular" },
|
||||||
{ label: "Plur.", value: "plural" },
|
{ label: "Plur.", value: "plural" },
|
||||||
]}
|
]}
|
||||||
value={noun.number}
|
value={props.noun.number}
|
||||||
handleChange={(n) => {
|
handleChange={(n) => {
|
||||||
if (!noun.changeNumber) return;
|
if (!props.noun || !props.noun.changeNumber) return;
|
||||||
onChange(noun.changeNumber(n));
|
props.onChange(props.noun.changeNumber(n));
|
||||||
}}
|
}}
|
||||||
/> : noun.number === "singular" ? "Sing." : "Plur."}
|
/> : props.noun.number === "singular" ? "Sing." : "Plur."}
|
||||||
</div>
|
</div>
|
||||||
</div>}
|
</div>}
|
||||||
</div>;
|
</div>;
|
||||||
|
|
|
@ -10,8 +10,12 @@ function makeParticipleSelection(verb: VerbEntry): ParticipleSelection {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function NPParticiplePicker({ onChange, participle, verbs, clearButton, opts }: {
|
function NPParticiplePicker(props: ({
|
||||||
verbs: VerbEntry[],
|
verbs: VerbEntry[],
|
||||||
|
} | {
|
||||||
|
verbs: (s: string) => VerbEntry[],
|
||||||
|
getVerbByTs: (ts: number) => VerbEntry | undefined;
|
||||||
|
}) & {
|
||||||
participle: ParticipleSelection | undefined,
|
participle: ParticipleSelection | undefined,
|
||||||
onChange: (p: ParticipleSelection | undefined) => void,
|
onChange: (p: ParticipleSelection | undefined) => void,
|
||||||
clearButton: JSX.Element,
|
clearButton: JSX.Element,
|
||||||
|
@ -19,21 +23,26 @@ function NPParticiplePicker({ onChange, participle, verbs, clearButton, opts }:
|
||||||
}) {
|
}) {
|
||||||
function onEntrySelect(entry: VerbEntry | undefined) {
|
function onEntrySelect(entry: VerbEntry | undefined) {
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
onChange(undefined);
|
props.onChange(undefined);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
onChange(makeParticipleSelection(entry));
|
props.onChange(makeParticipleSelection(entry));
|
||||||
}
|
}
|
||||||
return <div style={{ maxWidth: "225px" }}>
|
return <div style={{ maxWidth: "225px" }}>
|
||||||
{clearButton}
|
{props.clearButton}
|
||||||
<EntrySelect
|
<EntrySelect
|
||||||
value={participle?.verb}
|
value={props.participle?.verb}
|
||||||
entries={verbs}
|
{..."getVerbByTs" in props ? {
|
||||||
|
getByTs: props.getVerbByTs,
|
||||||
|
searchF: props.verbs,
|
||||||
|
} : {
|
||||||
|
entries: props.verbs,
|
||||||
|
}}
|
||||||
onChange={onEntrySelect}
|
onChange={onEntrySelect}
|
||||||
name="Pariticple"
|
name="Pariticple"
|
||||||
opts={opts}
|
opts={props.opts}
|
||||||
/>
|
/>
|
||||||
{participle && <div className="my-2 d-flex flex-row justify-content-around align-items-center">
|
{props.participle && <div className="my-2 d-flex flex-row justify-content-around align-items-center">
|
||||||
<div>Masc.</div>
|
<div>Masc.</div>
|
||||||
<div>Plur.</div>
|
<div>Plur.</div>
|
||||||
</div>}
|
</div>}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import ParticiplePicker from "./NPParticiplePicker";
|
||||||
// import { ButtonSelect } from "@lingdocs/pashto-inflector";
|
// import { ButtonSelect } from "@lingdocs/pashto-inflector";
|
||||||
import { randomPerson } from "../../lib/np-tools";
|
import { randomPerson } from "../../lib/np-tools";
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { nouns, verbs } from "../../words/words";
|
|
||||||
import {
|
import {
|
||||||
Types as T,
|
Types as T,
|
||||||
} from "@lingdocs/pashto-inflector";
|
} from "@lingdocs/pashto-inflector";
|
||||||
|
@ -13,38 +12,46 @@ import {
|
||||||
|
|
||||||
const npTypes: NPType[] = ["pronoun", "noun", "participle"];
|
const npTypes: NPType[] = ["pronoun", "noun", "participle"];
|
||||||
|
|
||||||
function NPPicker({ np, onChange, counterPart, asObject, opts }: {
|
function NPPicker(props: {
|
||||||
onChange: (nps: NPSelection | undefined) => void,
|
onChange: (nps: NPSelection | undefined) => void,
|
||||||
np: NPSelection | undefined,
|
np: NPSelection | undefined,
|
||||||
counterPart: NPSelection | VerbObject | undefined,
|
counterPart: NPSelection | VerbObject | undefined,
|
||||||
asObject?: boolean,
|
asObject?: boolean,
|
||||||
opts: T.TextOptions,
|
opts: T.TextOptions,
|
||||||
}) {
|
} & ({
|
||||||
const [npType, setNpType] = useState<NPType | undefined>(np ? np.type : undefined);
|
nouns: (s: string) => NounEntry[],
|
||||||
|
verbs: (s: string) => VerbEntry[],
|
||||||
|
getNounByTs: (ts: number) => NounEntry | undefined,
|
||||||
|
getVerbByTs: (ts: number) => VerbEntry | undefined,
|
||||||
|
} | {
|
||||||
|
nouns: NounEntry[],
|
||||||
|
verbs: VerbEntry[],
|
||||||
|
})) {
|
||||||
|
const [npType, setNpType] = useState<NPType | undefined>(props.np ? props.np.type : undefined);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setNpType(np ? np.type : undefined);
|
setNpType(props.np ? props.np.type : undefined);
|
||||||
}, [np]);
|
}, [props.np]);
|
||||||
function handleClear() {
|
function handleClear() {
|
||||||
if (np && np.type === "noun" && np.dynamicComplement) return;
|
if (props.np && props.np.type === "noun" && props.np.dynamicComplement) return;
|
||||||
setNpType(undefined);
|
setNpType(undefined);
|
||||||
onChange(undefined);
|
props.onChange(undefined);
|
||||||
}
|
}
|
||||||
function handleNPTypeChange(ntp: NPType) {
|
function handleNPTypeChange(ntp: NPType) {
|
||||||
if (ntp === "pronoun") {
|
if (ntp === "pronoun") {
|
||||||
const person = randomPerson({ counterPart });
|
const person = randomPerson({ counterPart: props.counterPart });
|
||||||
const pronoun: PronounSelection = {
|
const pronoun: PronounSelection = {
|
||||||
type: "pronoun",
|
type: "pronoun",
|
||||||
person,
|
person,
|
||||||
distance: "far",
|
distance: "far",
|
||||||
};
|
};
|
||||||
setNpType(ntp);
|
setNpType(ntp);
|
||||||
onChange(pronoun);
|
props.onChange(pronoun);
|
||||||
} else {
|
} else {
|
||||||
onChange(undefined);
|
props.onChange(undefined);
|
||||||
setNpType(ntp);
|
setNpType(ntp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const isDynamicComplement = np && np.type === "noun" && np.dynamicComplement;
|
const isDynamicComplement = props.np && props.np.type === "noun" && props.np.dynamicComplement;
|
||||||
const clearButton = <button className="btn btn-sm btn-light mb-2" onClick={handleClear}>X</button>;
|
const clearButton = <button className="btn btn-sm btn-light mb-2" onClick={handleClear}>X</button>;
|
||||||
return <div>
|
return <div>
|
||||||
{!npType && <div className="text-center mt-3">
|
{!npType && <div className="text-center mt-3">
|
||||||
|
@ -62,29 +69,39 @@ function NPPicker({ np, onChange, counterPart, asObject, opts }: {
|
||||||
</button>
|
</button>
|
||||||
</div>)}
|
</div>)}
|
||||||
</div>}
|
</div>}
|
||||||
{(npType === "pronoun" && np?.type === "pronoun")
|
{(npType === "pronoun" && props.np?.type === "pronoun")
|
||||||
? <PronounPicker
|
? <PronounPicker
|
||||||
asObject={asObject}
|
asObject={props.asObject}
|
||||||
pronoun={np}
|
pronoun={props.np}
|
||||||
onChange={onChange}
|
onChange={props.onChange}
|
||||||
clearButton={clearButton}
|
clearButton={clearButton}
|
||||||
opts={opts}
|
opts={props.opts}
|
||||||
/>
|
/>
|
||||||
: npType === "noun"
|
: npType === "noun"
|
||||||
? <NounPicker
|
? <NounPicker
|
||||||
nouns={nouns}
|
{..."getNounByTs" in props ? {
|
||||||
noun={(np && np.type === "noun") ? np : undefined}
|
nouns: props.nouns,
|
||||||
onChange={onChange}
|
getNounByTs: props.getNounByTs,
|
||||||
|
} : {
|
||||||
|
nouns: props.nouns,
|
||||||
|
}}
|
||||||
|
noun={(props.np && props.np.type === "noun") ? props.np : undefined}
|
||||||
|
onChange={props.onChange}
|
||||||
clearButton={!isDynamicComplement ? clearButton : undefined}
|
clearButton={!isDynamicComplement ? clearButton : undefined}
|
||||||
opts={opts}
|
opts={props.opts}
|
||||||
/>
|
/>
|
||||||
: npType === "participle"
|
: npType === "participle"
|
||||||
? <ParticiplePicker
|
? <ParticiplePicker
|
||||||
verbs={verbs}
|
{..."getVerbByTs" in props ? {
|
||||||
participle={(np && np.type === "participle") ? np : undefined}
|
verbs: props.verbs,
|
||||||
onChange={onChange}
|
getVerbByTs: props.getVerbByTs,
|
||||||
|
} : {
|
||||||
|
verbs: props.verbs,
|
||||||
|
}}
|
||||||
|
participle={(props.np && props.np.type === "participle") ? props.np : undefined}
|
||||||
|
onChange={props.onChange}
|
||||||
clearButton={clearButton}
|
clearButton={clearButton}
|
||||||
opts={opts}
|
opts={props.opts}
|
||||||
/>
|
/>
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,8 +33,16 @@ const servantEmoji = "🙇♂️";
|
||||||
// TODO: error handling on error with rendering etc
|
// TODO: error handling on error with rendering etc
|
||||||
export function PhraseBuilder(props: {
|
export function PhraseBuilder(props: {
|
||||||
verb?: VerbEntry,
|
verb?: VerbEntry,
|
||||||
opts?: T.TextOptions,
|
opts: T.TextOptions,
|
||||||
}) {
|
} & ({
|
||||||
|
nouns: NounEntry[],
|
||||||
|
verbs: VerbEntry[],
|
||||||
|
} | {
|
||||||
|
nouns: (s: string) => NounEntry[],
|
||||||
|
verbs: (s: string) => VerbEntry[],
|
||||||
|
getNounByTs: (ts: number) => NounEntry | undefined,
|
||||||
|
getVerbByTs: (ts: number) => VerbEntry | undefined,
|
||||||
|
})) {
|
||||||
const [subject, setSubject] = useStickyState<NPSelection | undefined>(undefined, "subjectNPSelection");
|
const [subject, setSubject] = useStickyState<NPSelection | undefined>(undefined, "subjectNPSelection");
|
||||||
const [mode, setMode] = useStickyState<"charts" | "phrases">("phrases", "verbExplorerMode");
|
const [mode, setMode] = useStickyState<"charts" | "phrases">("phrases", "verbExplorerMode");
|
||||||
const passedVerb = props.verb;
|
const passedVerb = props.verb;
|
||||||
|
@ -101,6 +109,15 @@ export function PhraseBuilder(props: {
|
||||||
<div className="my-2">
|
<div className="my-2">
|
||||||
<div className="h5 text-center">Subject {showRole(VPRendered, "subject")}</div>
|
<div className="h5 text-center">Subject {showRole(VPRendered, "subject")}</div>
|
||||||
<NPPicker
|
<NPPicker
|
||||||
|
{..."getNounByTs" in props ? {
|
||||||
|
getNounByTs: props.getNounByTs,
|
||||||
|
getVerbByTs: props.getVerbByTs,
|
||||||
|
nouns: props.nouns,
|
||||||
|
verbs: props.verbs,
|
||||||
|
} : {
|
||||||
|
nouns: props.nouns,
|
||||||
|
verbs: props.verbs,
|
||||||
|
}}
|
||||||
np={subject}
|
np={subject}
|
||||||
counterPart={verb ? verb.object : undefined}
|
counterPart={verb ? verb.object : undefined}
|
||||||
onChange={handleSubjectChange}
|
onChange={handleSubjectChange}
|
||||||
|
@ -112,6 +129,15 @@ export function PhraseBuilder(props: {
|
||||||
{(typeof verb.object === "number")
|
{(typeof verb.object === "number")
|
||||||
? <div className="text-muted">Unspoken 3rd Pers. Masc. Plur.</div>
|
? <div className="text-muted">Unspoken 3rd Pers. Masc. Plur.</div>
|
||||||
: <NPPicker
|
: <NPPicker
|
||||||
|
{..."getNounByTs" in props ? {
|
||||||
|
getNounByTs: props.getNounByTs,
|
||||||
|
getVerbByTs: props.getVerbByTs,
|
||||||
|
nouns: props.nouns,
|
||||||
|
verbs: props.verbs,
|
||||||
|
} : {
|
||||||
|
nouns: props.nouns,
|
||||||
|
verbs: props.verbs,
|
||||||
|
}}
|
||||||
asObject
|
asObject
|
||||||
np={verb.object}
|
np={verb.object}
|
||||||
counterPart={subject}
|
counterPart={subject}
|
||||||
|
|
|
@ -4,5 +4,13 @@ fullWidth: true
|
||||||
---
|
---
|
||||||
|
|
||||||
import PhraseBuilder from "../../components/phrase-builder/PhraseBuilder";
|
import PhraseBuilder from "../../components/phrase-builder/PhraseBuilder";
|
||||||
|
import {
|
||||||
|
defaultTextOptions,
|
||||||
|
} from "@lingdocs/pashto-inflector";
|
||||||
|
import { nouns, verbs } from "../../words/words";
|
||||||
|
|
||||||
<PhraseBuilder />
|
<PhraseBuilder
|
||||||
|
opts={defaultTextOptions}
|
||||||
|
nouns={nouns}
|
||||||
|
verbs={verbs}
|
||||||
|
/>
|
Loading…
Reference in New Issue