add formulas and fix dark mode bad select colors
This commit is contained in:
parent
5dc01ee1ab
commit
e2844f9bf4
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@lingdocs/pashto-inflector",
|
"name": "@lingdocs/pashto-inflector",
|
||||||
"version": "2.1.7",
|
"version": "2.1.8",
|
||||||
"author": "lingdocs.com",
|
"author": "lingdocs.com",
|
||||||
"description": "A Pashto inflection and verb conjugation engine, inculding React components for displaying Pashto text, inflections, and conjugations",
|
"description": "A Pashto inflection and verb conjugation engine, inculding React components for displaying Pashto text, inflections, and conjugations",
|
||||||
"homepage": "https://verbs.lingdocs.com",
|
"homepage": "https://verbs.lingdocs.com",
|
||||||
|
|
|
@ -26,7 +26,7 @@ import * as T from "./types";
|
||||||
import { isNounEntry } from "./lib/type-predicates";
|
import { isNounEntry } from "./lib/type-predicates";
|
||||||
import defualtTextOptions from "./lib/default-text-options";
|
import defualtTextOptions from "./lib/default-text-options";
|
||||||
import PhraseBuilder from "./components/vp-explorer/VPExplorer";
|
import PhraseBuilder from "./components/vp-explorer/VPExplorer";
|
||||||
import { useStickyState } from "./library";
|
import useStickyState from "./lib/useStickyState";
|
||||||
type VerbType = "simple" | "stative compound" | "dynamic compound";
|
type VerbType = "simple" | "stative compound" | "dynamic compound";
|
||||||
const verbTypes: VerbType[] = [
|
const verbTypes: VerbType[] = [
|
||||||
"simple",
|
"simple",
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
makeVerbSelectOption,
|
makeVerbSelectOption,
|
||||||
} from "./np-picker/picker-tools";
|
} from "./np-picker/picker-tools";
|
||||||
|
|
||||||
const customStyles: StylesConfig = {
|
export const customStyles: StylesConfig = {
|
||||||
menuPortal: (base) => ({
|
menuPortal: (base) => ({
|
||||||
...base,
|
...base,
|
||||||
zIndex: 99999,
|
zIndex: 99999,
|
||||||
|
@ -19,17 +19,12 @@ const customStyles: StylesConfig = {
|
||||||
option: (provided, state) => ({
|
option: (provided, state) => ({
|
||||||
...provided,
|
...provided,
|
||||||
padding: "10px 5px",
|
padding: "10px 5px",
|
||||||
|
color: "#121418",
|
||||||
}),
|
}),
|
||||||
input: (base) => ({
|
input: (base) => ({
|
||||||
...base,
|
...base,
|
||||||
padding: 0,
|
padding: 0,
|
||||||
}),
|
}),
|
||||||
singleValue: (provided, state) => {
|
|
||||||
const opacity = state.isDisabled ? 0.5 : 1;
|
|
||||||
const transition = 'opacity 300ms';
|
|
||||||
|
|
||||||
return { ...provided, opacity, transition };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function EntrySelect<E extends T.DictionaryEntry | T.VerbEntry>(props: ({
|
function EntrySelect<E extends T.DictionaryEntry | T.VerbEntry>(props: ({
|
||||||
|
@ -108,7 +103,7 @@ function EntrySelect<E extends T.DictionaryEntry | T.VerbEntry>(props: ({
|
||||||
styles={customStyles}
|
styles={customStyles}
|
||||||
isSearchable={true}
|
isSearchable={true}
|
||||||
value={value}
|
value={value}
|
||||||
// @ts-ignore
|
// @ts-ignore - gets messed up when using customStyles
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
className="mb-2"
|
className="mb-2"
|
||||||
options={options}
|
options={options}
|
||||||
|
|
|
@ -23,11 +23,6 @@ import {
|
||||||
translatePhonetics,
|
translatePhonetics,
|
||||||
} from "../../lib/translate-phonetics";
|
} from "../../lib/translate-phonetics";
|
||||||
|
|
||||||
export const zIndexProps = {
|
|
||||||
menuPortalTarget: document.body,
|
|
||||||
styles: { menuPortal: (base: any) => ({ ...base, zIndex: 9999 }) },
|
|
||||||
};
|
|
||||||
|
|
||||||
export function makeVerbSelectOption(e: T.VerbEntry, opts: T.TextOptions): { value: string, label: string | JSX.Element } {
|
export function makeVerbSelectOption(e: T.VerbEntry, opts: T.TextOptions): { value: string, label: string | JSX.Element } {
|
||||||
const engV = getEnglishVerb(e.entry);
|
const engV = getEnglishVerb(e.entry);
|
||||||
const eng = engV || truncateEnglish(e.entry.e);
|
const eng = engV || truncateEnglish(e.entry.e);
|
||||||
|
|
|
@ -1,67 +1,83 @@
|
||||||
import Select from "react-select";
|
import Select from "react-select";
|
||||||
import {
|
|
||||||
zIndexProps,
|
|
||||||
} from "../np-picker/picker-tools";
|
|
||||||
import * as T from "../../types";
|
import * as T from "../../types";
|
||||||
import ButtonSelect from "../ButtonSelect";
|
import ButtonSelect from "../ButtonSelect";
|
||||||
import { isImperativeTense, isModalTense, isPerfectTense, isVerbTense } from "../../lib/type-predicates";
|
import { isImperativeTense, isModalTense, isPerfectTense, isVerbTense } from "../../lib/type-predicates";
|
||||||
import { ensure2ndPersSubjPronounAndNoConflict } from "../../lib/phrase-building/vp-tools";
|
import { ensure2ndPersSubjPronounAndNoConflict } from "../../lib/phrase-building/vp-tools";
|
||||||
|
import useStickyState from "../../lib/useStickyState";
|
||||||
|
import { customStyles } from "../EntrySelect";
|
||||||
|
|
||||||
const verbTenseOptions: { label: string | JSX.Element, value: T.VerbTense }[] = [{
|
const verbTenseOptions: { label: string | JSX.Element, value: T.VerbTense, formula: string }[] = [{
|
||||||
label: <div><i className="fas fa-video mr-2" />present</div>,
|
label: <div><i className="fas fa-video mr-2" />present</div>,
|
||||||
value: "presentVerb",
|
value: "presentVerb",
|
||||||
|
formula: "imperfective stem + present verb ending",
|
||||||
}, {
|
}, {
|
||||||
label: <div><i className="fas fa-camera mr-2" />subjunctive</div>,
|
label: <div><i className="fas fa-camera mr-2" />subjunctive</div>,
|
||||||
value: "subjunctiveVerb",
|
value: "subjunctiveVerb",
|
||||||
|
formula: "perfective stem + present verb ending",
|
||||||
}, {
|
}, {
|
||||||
label: <div><i className="fas fa-video mr-2" />imperfective future</div>,
|
label: <div><i className="fas fa-video mr-2" />imperfective future</div>,
|
||||||
value: "imperfectiveFuture",
|
value: "imperfectiveFuture",
|
||||||
|
formula: "ba + present",
|
||||||
}, {
|
}, {
|
||||||
label: <div><i className="fas fa-camera mr-2" />perfective future</div>,
|
label: <div><i className="fas fa-camera mr-2" />perfective future</div>,
|
||||||
value: "perfectiveFuture",
|
value: "perfectiveFuture",
|
||||||
|
formula: "ba + subjunctive",
|
||||||
}, {
|
}, {
|
||||||
label: <div><i className="fas fa-video mr-2" />continuous past</div>,
|
label: <div><i className="fas fa-video mr-2" />continuous past</div>,
|
||||||
value: "imperfectivePast",
|
value: "imperfectivePast",
|
||||||
|
formula: "imperfective root + past verb ending",
|
||||||
}, {
|
}, {
|
||||||
label: <div><i className="fas fa-camera mr-2" />simple past</div>,
|
label: <div><i className="fas fa-camera mr-2" />simple past</div>,
|
||||||
value: "perfectivePast",
|
value: "perfectivePast",
|
||||||
|
formula: "perfective root + past verb ending",
|
||||||
}, {
|
}, {
|
||||||
label: <div><i className="fas fa-video mr-2" />habitual continual past</div>,
|
label: <div><i className="fas fa-video mr-2" />habitual continual past</div>,
|
||||||
value: "habitualImperfectivePast",
|
value: "habitualImperfectivePast",
|
||||||
|
formula: "ba + contiunous past",
|
||||||
}, {
|
}, {
|
||||||
label: <div><i className="fas fa-camera mr-2" />habitual simple past</div>,
|
label: <div><i className="fas fa-camera mr-2" />habitual simple past</div>,
|
||||||
value: "habitualPerfectivePast",
|
value: "habitualPerfectivePast",
|
||||||
|
formula: "ba + simple past",
|
||||||
}];
|
}];
|
||||||
|
|
||||||
const perfectTenseOptions: { label: string | JSX.Element, value: T.PerfectTense }[] = [{
|
const perfectTenseOptions: { label: string | JSX.Element, value: T.PerfectTense, formula: string }[] = [{
|
||||||
label: "Present Perfect",
|
label: "Present Perfect",
|
||||||
value: "presentPerfect",
|
value: "presentPerfect",
|
||||||
|
formula: "past participle + present equative",
|
||||||
}, {
|
}, {
|
||||||
label: "Habitual Perfect",
|
label: "Habitual Perfect",
|
||||||
value: "habitualPerfect",
|
value: "habitualPerfect",
|
||||||
|
formula: "past participle + habitual equative",
|
||||||
}, {
|
}, {
|
||||||
label: "Subjunctive Perfect",
|
label: "Subjunctive Perfect",
|
||||||
value: "subjunctivePerfect",
|
value: "subjunctivePerfect",
|
||||||
|
formula: "past participle + subjunctive equative",
|
||||||
}, {
|
}, {
|
||||||
label: "Future Perfect",
|
label: "Future Perfect",
|
||||||
value: "futurePerfect",
|
value: "futurePerfect",
|
||||||
|
formula: "past participle + future equative",
|
||||||
}, {
|
}, {
|
||||||
label: "Past Perfect",
|
label: "Past Perfect",
|
||||||
value: "pastPerfect",
|
value: "pastPerfect",
|
||||||
|
formula: "past participle + past equative",
|
||||||
}, {
|
}, {
|
||||||
label: `"Would Be" Perfect`,
|
label: `"Would Be" Perfect`,
|
||||||
value: "wouldBePerfect",
|
value: "wouldBePerfect",
|
||||||
|
formula: `past participle + "would be" equative`,
|
||||||
}, {
|
}, {
|
||||||
label: "Past Subjunctive Perfect",
|
label: "Past Subjunctive Perfect",
|
||||||
value: "pastSubjunctivePerfect",
|
value: "pastSubjunctivePerfect",
|
||||||
|
formula: "past participle + past subjunctive equative",
|
||||||
}];
|
}];
|
||||||
|
|
||||||
const imperativeTenseOptions: { label: string | JSX.Element, value: T.ImperativeTense }[] = [{
|
const imperativeTenseOptions: { label: string | JSX.Element, value: T.ImperativeTense, formula: string }[] = [{
|
||||||
label: <div><i className="fas fa-video mr-2" />imperfective imperative</div>,
|
label: <div><i className="fas fa-video mr-2" />imperfective imperative</div>,
|
||||||
value: "imperfectiveImperative",
|
value: "imperfectiveImperative",
|
||||||
|
formula: "imperfective stem + imperative ending",
|
||||||
}, {
|
}, {
|
||||||
label: <div><i className="fas fa-camera mr-2" />perfective imperative</div>,
|
label: <div><i className="fas fa-camera mr-2" />perfective imperative</div>,
|
||||||
value: "perfectiveImperative",
|
value: "perfectiveImperative",
|
||||||
|
formula: "perfective stem + imperative ending",
|
||||||
}];
|
}];
|
||||||
|
|
||||||
export function getRandomTense(o?: T.PerfectTense | T.VerbTense | T.ModalTense | T.ImperativeTense): T.PerfectTense | T.VerbTense | T.ModalTense | T.ImperativeTense {
|
export function getRandomTense(o?: T.PerfectTense | T.VerbTense | T.ModalTense | T.ImperativeTense): T.PerfectTense | T.VerbTense | T.ModalTense | T.ImperativeTense {
|
||||||
|
@ -92,6 +108,7 @@ function TensePicker(props: ({
|
||||||
onChange: (p: T.VPSelection) => void,
|
onChange: (p: T.VPSelection) => void,
|
||||||
mode: "charts" | "phrases" | "quiz",
|
mode: "charts" | "phrases" | "quiz",
|
||||||
}) {
|
}) {
|
||||||
|
const [showFormula, setShowFormula] = useStickyState<boolean>(false, "showFormula");
|
||||||
function onTenseSelect(o: { value: T.VerbTense | T.PerfectTense | T.ImperativeTense } | null) {
|
function onTenseSelect(o: { value: T.VerbTense | T.PerfectTense | T.ImperativeTense } | null) {
|
||||||
if ("vpsComplete" in props) return;
|
if ("vpsComplete" in props) return;
|
||||||
const value = o?.value ? o.value : undefined;
|
const value = o?.value ? o.value : undefined;
|
||||||
|
@ -199,9 +216,15 @@ function TensePicker(props: ({
|
||||||
: verbTenseOptions;
|
: verbTenseOptions;
|
||||||
const showImperativeOption = ("vps" in props && props.vps.verb.voice === "active")
|
const showImperativeOption = ("vps" in props && props.vps.verb.voice === "active")
|
||||||
|| ("vpsComplete" in props && props.vpsComplete.verb.voice !== "active");
|
|| ("vpsComplete" in props && props.vpsComplete.verb.voice !== "active");
|
||||||
|
const canShowFormula = "vps" in props && props.vps.verb.tenseCategory !== "modal";
|
||||||
return <div>
|
return <div>
|
||||||
<div style={{ maxWidth: "300px", minWidth: "250px", margin: "0 auto" }}>
|
<div style={{ maxWidth: "300px", minWidth: "250px", margin: "0 auto" }}>
|
||||||
|
<div className="d-flex flex-row justify-content-between align-items-center">
|
||||||
<div className="h5">Tense:</div>
|
<div className="h5">Tense:</div>
|
||||||
|
{canShowFormula && <div className="clickable mb-2 small" onClick={() => setShowFormula(x => !x)}>
|
||||||
|
🧪 {!showFormula ? "Show" : "Hide"} Formula
|
||||||
|
</div>}
|
||||||
|
</div>
|
||||||
{("vpsComplete" in props || props.vps.verb) && <div className="mb-2">
|
{("vpsComplete" in props || props.vps.verb) && <div className="mb-2">
|
||||||
<ButtonSelect
|
<ButtonSelect
|
||||||
small
|
small
|
||||||
|
@ -237,7 +260,8 @@ function TensePicker(props: ({
|
||||||
? <div style={{ fontSize: "larger" }} className="mb-3">
|
? <div style={{ fontSize: "larger" }} className="mb-3">
|
||||||
{[...verbTenseOptions, ...perfectTenseOptions, ...imperativeTenseOptions].find(o => o.value === props.vpsComplete.verb.tense)?.label}
|
{[...verbTenseOptions, ...perfectTenseOptions, ...imperativeTenseOptions].find(o => o.value === props.vpsComplete.verb.tense)?.label}
|
||||||
</div>
|
</div>
|
||||||
: <Select
|
: <>
|
||||||
|
<Select
|
||||||
isSearchable={false}
|
isSearchable={false}
|
||||||
// for some reason can't use tOptions with find here;
|
// for some reason can't use tOptions with find here;
|
||||||
value={props.vps.verb && ([...verbTenseOptions, ...perfectTenseOptions, ...imperativeTenseOptions].find(o => o.value === props.vps.verb[
|
value={props.vps.verb && ([...verbTenseOptions, ...perfectTenseOptions, ...imperativeTenseOptions].find(o => o.value === props.vps.verb[
|
||||||
|
@ -247,12 +271,14 @@ function TensePicker(props: ({
|
||||||
? "imperativeTense"
|
? "imperativeTense"
|
||||||
: "verbTense"
|
: "verbTense"
|
||||||
]))}
|
]))}
|
||||||
|
// @ts-ignore - gets messed up when using customStyles
|
||||||
onChange={onTenseSelect}
|
onChange={onTenseSelect}
|
||||||
className="mb-2"
|
className="mb-2"
|
||||||
options={tOptions}
|
options={tOptions}
|
||||||
{...zIndexProps}
|
styles={customStyles}
|
||||||
/>}
|
/>
|
||||||
{"vps" in props && props.vps.verb && (props.mode !== "quiz") && <div className="d-flex flex-row justify-content-between align-items-center mt-3 mb-1" style={{ width: "100%" }}>
|
</>}
|
||||||
|
{"vps" in props && props.vps.verb && (props.mode !== "quiz") && <div className="d-flex flex-row justify-content-between align-items-center mt-2 mb-1" style={{ width: "100%" }}>
|
||||||
<div className="btn btn-light clickable" onClick={moveTense("back")}>
|
<div className="btn btn-light clickable" onClick={moveTense("back")}>
|
||||||
<i className="fas fa-chevron-left" />
|
<i className="fas fa-chevron-left" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -272,6 +298,23 @@ function TensePicker(props: ({
|
||||||
<i className="fas fa-chevron-right" />
|
<i className="fas fa-chevron-right" />
|
||||||
</div>
|
</div>
|
||||||
</div>}
|
</div>}
|
||||||
|
{(canShowFormula && "vps" in props && showFormula && props.vps.verb.tenseCategory !== "modal") && (() => {
|
||||||
|
// TODO: Be able to show modal formulas too
|
||||||
|
const curr = (props.vps.verb.tenseCategory === "imperative" && props.vps.verb.negative)
|
||||||
|
? imperativeTenseOptions.find(x => x.value === "imperfectiveImperative")
|
||||||
|
: [...verbTenseOptions, ...perfectTenseOptions, ...imperativeTenseOptions].find(o => o.value === props.vps.verb[
|
||||||
|
props.vps.verb.tenseCategory === "perfect"
|
||||||
|
? "perfectTense"
|
||||||
|
: props.vps.verb.tenseCategory === "imperative"
|
||||||
|
? "imperativeTense"
|
||||||
|
: "verbTense"
|
||||||
|
]);
|
||||||
|
if (curr && "formula" in curr) {
|
||||||
|
return <div style={{ width: "250px", overflowY: "auto" }}>
|
||||||
|
<samp>{curr.formula}</samp>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
})()}
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {
|
||||||
isPastTense,
|
isPastTense,
|
||||||
completeVPSelection,
|
completeVPSelection,
|
||||||
} from "../../lib/phrase-building/vp-tools";
|
} from "../../lib/phrase-building/vp-tools";
|
||||||
import { useStickyState } from "../../library";
|
import useStickyState from "../../lib/useStickyState";
|
||||||
import Examples from "../Examples";
|
import Examples from "../Examples";
|
||||||
|
|
||||||
function VPDisplay({ VP, opts }: { VP: T.VPSelection, opts: T.TextOptions }) {
|
function VPDisplay({ VP, opts }: { VP: T.VPSelection, opts: T.TextOptions }) {
|
||||||
|
|
|
@ -47,7 +47,9 @@ export function revertSpelling(input: string, spelling: T.Spelling): string {
|
||||||
: "ي"}(?![\u0621-\u065f\u0670-\u06d3\u06d5])`, "g"), "ي")
|
: "ي"}(?![\u0621-\u065f\u0670-\u06d3\u06d5])`, "g"), "ي")
|
||||||
.replace(/ے(?![\u0621-\u065f\u0670-\u06d3\u06d5])/g, "ی")
|
.replace(/ے(?![\u0621-\u065f\u0670-\u06d3\u06d5])/g, "ی")
|
||||||
.replace(/ائ(?![\u0621-\u065f\u0670-\u06d3\u06d5])/g, "ای")
|
.replace(/ائ(?![\u0621-\u065f\u0670-\u06d3\u06d5])/g, "ای")
|
||||||
|
.replace(/اے(?![\u0621-\u065f\u0670-\u06d3\u06d5])/g, "ای")
|
||||||
.replace(/وئ(?![\u0621-\u065f\u0670-\u06d3\u06d5])/g, "وی")
|
.replace(/وئ(?![\u0621-\u065f\u0670-\u06d3\u06d5])/g, "وی")
|
||||||
|
.replace(/وے(?![\u0621-\u065f\u0670-\u06d3\u06d5])/g, "وی")
|
||||||
.replace(/(?:ائی|ائي)(?=[\u0621-\u065f\u0670-\u06d3\u06d5])/g, "اي")
|
.replace(/(?:ائی|ائي)(?=[\u0621-\u065f\u0670-\u06d3\u06d5])/g, "اي")
|
||||||
.replace(/(?:وئی|وئي)(?=[\u0621-\u065f\u0670-\u06d3\u06d5])/g, "وي")
|
.replace(/(?:وئی|وئي)(?=[\u0621-\u065f\u0670-\u06d3\u06d5])/g, "وي")
|
||||||
.replace(/ائ(?=ي|ی|ې)/g, "اي")
|
.replace(/ائ(?=ي|ی|ې)/g, "اي")
|
||||||
|
|
|
@ -27,7 +27,7 @@ import {
|
||||||
isPerfectTense,
|
isPerfectTense,
|
||||||
} from "../type-predicates";
|
} from "../type-predicates";
|
||||||
import { renderEnglishVPBase } from "./english-vp-rendering";
|
import { renderEnglishVPBase } from "./english-vp-rendering";
|
||||||
import { personGender } from "../../library";
|
import { personGender } from "../../lib/misc-helpers";
|
||||||
|
|
||||||
// TODO: ISSUE GETTING SPLIT HEAD NOT MATCHING WITH FUTURE VERBS
|
// TODO: ISSUE GETTING SPLIT HEAD NOT MATCHING WITH FUTURE VERBS
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue