remove rollup and see if it works w/out react-select

This commit is contained in:
adueck 2022-10-06 17:36:01 +05:00
parent 7b02179bf7
commit aa17c342d8
6 changed files with 442 additions and 502 deletions

View File

@ -1,14 +1,11 @@
{
"name": "@lingdocs/pashto-inflector",
"version": "4.9.13",
"version": "4.9.14",
"author": "lingdocs.com",
"description": "A Pashto inflection and verb conjugation engine, inculding React components for displaying Pashto text, inflections, and conjugations",
"homepage": "https://verbs.lingdocs.com",
"license": "MIT",
"exports": {
"./functions": "./dist-cjs/dist/functions.js",
"./components": "./dist-cjs/dist/components.js"
},
"main": "dist-cjs/library.js",
"module": "dist/library.js",
"types": "dist/library.d.ts",
"private": false,
@ -30,8 +27,7 @@
"jsurl2": "^2.1.0",
"lz-string": "^1.4.4",
"pbf": "^3.2.1",
"rambda": "^6.7.0",
"react-select": "^4.3.1"
"rambda": "^6.7.0"
},
"devDependencies": {
"@fortawesome/fontawesome-free": "^5.15.2",
@ -73,7 +69,7 @@
"test": "react-scripts test",
"eject": "react-scripts eject",
"build-website": "node get-words.js && npm run build",
"build-library": "node get-words.js && rimraf dist && rimraf dist-cjs && tsc --project library-tsconfig.json && node library-post-build.js && rollup -c",
"build-library": "node get-words.js && rimraf dist && tsc --project library-tsconfig.json && node library-post-build.js",
"test-ci": "npm run test -- --watchAll=false",
"get-words": "node get-words.js"
},

View File

@ -1,36 +0,0 @@
import image from '@rollup/plugin-image';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import pkg from './package.json';
import multiInput from 'rollup-plugin-multi-input';
const banner = `
/**
* Copyright (c) 2021 lingdocs.com
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
`;
export default {
input: ['dist/functions.js', 'dist/components.js'],
external: ["react", "react-dom", "react-bootstrap"],
output: [{
dir: "dist-cjs",
format: 'cjs',
sourcemap: true,
banner,
}],
plugins: [
// peerDepsExternal(),
multiInput(),
commonjs(),
nodeResolve({
resolveOnly: Object.keys(pkg.dependencies),
}),
// use base64 image inlining for the cjs version so that the .svg s can get cosumed by node 12 etc.
image(),
]
}

View File

@ -1,33 +1,31 @@
import * as T from "../types";
import { StyleHTMLAttributes } from "react";
// @ts-ignore
import Select, { StylesConfig } from "react-select";
// @ts-ignore
import AsyncSelect from "react-select/async";
import {
makeSelectOption,
makeVerbSelectOption,
} from "./np-picker/picker-tools";
// import Select, { StylesConfig } from "react-select";
// import AsyncSelect from "react-select/async";
// import {
// makeSelectOption,
// makeVerbSelectOption,
// } from "./np-picker/picker-tools";
export const customStyles: StylesConfig = {
menuPortal: (base: any) => ({
...base,
zIndex: 99999,
}),
menu: (base: any) => ({
...base,
zIndex: 999999,
}),
option: (provided: any, state: any) => ({
...provided,
padding: "10px 5px",
color: "#121418",
}),
input: (base: any) => ({
...base,
padding: 0,
}),
}
// export const customStyles: StylesConfig = {
// menuPortal: (base: any) => ({
// ...base,
// zIndex: 99999,
// }),
// menu: (base: any) => ({
// ...base,
// zIndex: 999999,
// }),
// option: (provided: any, state: any) => ({
// ...provided,
// padding: "10px 5px",
// color: "#121418",
// }),
// input: (base: any) => ({
// ...base,
// padding: 0,
// }),
// }
function EntrySelect<E extends T.DictionaryEntry | T.VerbEntry>(props: {
entryFeeder: T.EntryFeederSingleType<E>,
@ -38,79 +36,80 @@ function EntrySelect<E extends T.DictionaryEntry | T.VerbEntry>(props: {
opts: T.TextOptions,
style?: StyleHTMLAttributes<HTMLDivElement>,
}) {
const divStyle = props.style || { width: "13rem" };
const placeholder = "entries" in props ? "Select…" : "Search Pashto";
function makeOption(e: E | T.DictionaryEntry) {
if ("entry" in e) {
return (props.isVerbSelect ? makeVerbSelectOption : makeSelectOption)(e, props.opts);
}
return makeSelectOption(e, props.opts);
}
const value = props.value ? makeOption(props.value) : undefined;
if ("search" in props.entryFeeder) {
const search = props.entryFeeder.search;
const getByTs = props.entryFeeder.getByTs;
const options = (searchString: string) =>
new Promise<{ value: string, label: string | JSX.Element }[]>(resolve => {
resolve(search(searchString).map(makeOption));
});
const onChange = (v: { label: string | JSX.Element, value: string } | null) => {
if (!v) {
props.onChange(undefined);
return;
}
const s = getByTs(parseInt(v.value));
if (!s) return;
props.onChange(s);
}
return <div style={divStyle}>
<AsyncSelect
styles={customStyles}
isSearchable={true}
className="mb-2"
value={value}
// @ts-ignore
onChange={onChange}
defaultOptions={[]}
loadOptions={options}
placeholder={placeholder}
/>
</div>;
}
const entries = props.entryFeeder;
const options = entries
.sort((a, b) => {
if ("entry" in a) {
return a.entry.p.localeCompare("p" in b ? b.p : b.entry.p, "af-PS")
}
return a.p.localeCompare("p" in b ? b.p : b.entry.p, "af-PS");
})
.map(makeOption);
const onChange = (v: { label: string | JSX.Element, value: string } | null) => {
if (!v) {
props.onChange(undefined);
return;
}
const s = entries.find(e => (
("entry" in e)
? e.entry.ts.toString() === v.value
: e.ts.toString() === v.value
));
if (!s) return;
props.onChange(s);
}
return <div style={divStyle}>
<Select
styles={customStyles}
isSearchable={true}
value={value}
// @ts-ignore - gets messed up when using customStyles
onChange={onChange}
className="mb-2"
options={options}
placeholder={placeholder}
/>
</div>
return <div>not here</div>;
// const divStyle = props.style || { width: "13rem" };
// const placeholder = "entries" in props ? "Select…" : "Search Pashto";
// function makeOption(e: E | T.DictionaryEntry) {
// if ("entry" in e) {
// return (props.isVerbSelect ? makeVerbSelectOption : makeSelectOption)(e, props.opts);
// }
// return makeSelectOption(e, props.opts);
// }
// const value = props.value ? makeOption(props.value) : undefined;
// if ("search" in props.entryFeeder) {
// const search = props.entryFeeder.search;
// const getByTs = props.entryFeeder.getByTs;
// const options = (searchString: string) =>
// new Promise<{ value: string, label: string | JSX.Element }[]>(resolve => {
// resolve(search(searchString).map(makeOption));
// });
// const onChange = (v: { label: string | JSX.Element, value: string } | null) => {
// if (!v) {
// props.onChange(undefined);
// return;
// }
// const s = getByTs(parseInt(v.value));
// if (!s) return;
// props.onChange(s);
// }
// return <div style={divStyle}>
// <AsyncSelect
// styles={customStyles}
// isSearchable={true}
// className="mb-2"
// value={value}
// // @ts-ignore
// onChange={onChange}
// defaultOptions={[]}
// loadOptions={options}
// placeholder={placeholder}
// />
// </div>;
// }
// const entries = props.entryFeeder;
// const options = entries
// .sort((a, b) => {
// if ("entry" in a) {
// return a.entry.p.localeCompare("p" in b ? b.p : b.entry.p, "af-PS")
// }
// return a.p.localeCompare("p" in b ? b.p : b.entry.p, "af-PS");
// })
// .map(makeOption);
// const onChange = (v: { label: string | JSX.Element, value: string } | null) => {
// if (!v) {
// props.onChange(undefined);
// return;
// }
// const s = entries.find(e => (
// ("entry" in e)
// ? e.entry.ts.toString() === v.value
// : e.ts.toString() === v.value
// ));
// if (!s) return;
// props.onChange(s);
// }
// return <div style={divStyle}>
// <Select
// styles={customStyles}
// isSearchable={true}
// value={value}
// // @ts-ignore - gets messed up when using customStyles
// onChange={onChange}
// className="mb-2"
// options={options}
// placeholder={placeholder}
// />
// </div>
}
export function SandwichSelect<E extends T.Sandwich>(props: {
@ -121,62 +120,63 @@ export function SandwichSelect<E extends T.Sandwich>(props: {
opts: T.TextOptions,
style?: StyleHTMLAttributes<HTMLDivElement>,
}) {
const divStyle = props.style || { width: "13rem" };
const placeholder = "Select Sandwich…";
const value = props.value ? makeSandwichOption(props.value) : undefined;
const options = props.sandwiches
// .sort((a, b) => {
// if ("entry" in a) {
// return a.before.p.localeCompare("p" in b ? b.p : b.entry.p, "af-PS")
// }
// return a.p.localeCompare("p" in b ? b.p : b.entry.p, "af-PS");
// })
.map(makeSandwichOption);
const onChange = (v: { label: string | JSX.Element, value: string } | null) => {
if (!v) {
props.onChange(undefined);
return;
}
const s = props.sandwiches.find(e => {
const sValue = JSON.parse(v.value) as T.Sandwich;
if (sValue.type !== "sandwich") throw new Error("error converting selected sandwich value to a sandwich");
return sandwichSideEq(e.before, sValue.before)
&& sandwichSideEq(e.after, sValue.after)
&& (e.e === sValue.e);
});
if (!s) return;
props.onChange(s);
}
return <div style={divStyle}>
<div>Sandwich Base</div>
<Select
styles={customStyles}
isSearchable={true}
value={value}
// @ts-ignore - gets messed up when using customStyles
onChange={onChange}
className="mb-2"
options={options}
placeholder={placeholder}
/>
</div>
return <div>not here</div>;
// const divStyle = props.style || { width: "13rem" };
// const placeholder = "Select Sandwich…";
// const value = props.value ? makeSandwichOption(props.value) : undefined;
// const options = props.sandwiches
// // .sort((a, b) => {
// // if ("entry" in a) {
// // return a.before.p.localeCompare("p" in b ? b.p : b.entry.p, "af-PS")
// // }
// // return a.p.localeCompare("p" in b ? b.p : b.entry.p, "af-PS");
// // })
// .map(makeSandwichOption);
// const onChange = (v: { label: string | JSX.Element, value: string } | null) => {
// if (!v) {
// props.onChange(undefined);
// return;
// }
// const s = props.sandwiches.find(e => {
// const sValue = JSON.parse(v.value) as T.Sandwich;
// if (sValue.type !== "sandwich") throw new Error("error converting selected sandwich value to a sandwich");
// return sandwichSideEq(e.before, sValue.before)
// && sandwichSideEq(e.after, sValue.after)
// && (e.e === sValue.e);
// });
// if (!s) return;
// props.onChange(s);
// }
// return <div style={divStyle}>
// <div>Sandwich Base</div>
// <Select
// styles={customStyles}
// isSearchable={true}
// value={value}
// // @ts-ignore - gets messed up when using customStyles
// onChange={onChange}
// className="mb-2"
// options={options}
// placeholder={placeholder}
// />
// </div>
}
function sandwichSideEq(s1: T.PsString | undefined, s2: T.PsString | undefined): boolean {
if (s1 === undefined && s2 === undefined) {
return true
}
if (typeof s1 === "object" && typeof s2 === "object" && s1.p === s2.p) {
return true;
}
return false;
}
// function sandwichSideEq(s1: T.PsString | undefined, s2: T.PsString | undefined): boolean {
// if (s1 === undefined && s2 === undefined) {
// return true
// }
// if (typeof s1 === "object" && typeof s2 === "object" && s1.p === s2.p) {
// return true;
// }
// return false;
// }
function makeSandwichOption(s: T.Sandwich): { label: string, value: string } {
return {
label: `${s.before ? s.before.p : ""} ... ${s.after ? s.after.p : ""} (${s.e})`,
value: JSON.stringify(s),
};
}
// function makeSandwichOption(s: T.Sandwich): { label: string, value: string } {
// return {
// label: `${s.before ? s.before.p : ""} ... ${s.after ? s.after.p : ""} (${s.e})`,
// value: JSON.stringify(s),
// };
// }
export default EntrySelect;

View File

@ -1,111 +1,111 @@
import * as T from "../../types"
// @ts-ignore
import Select from "react-select";
import ButtonSelect from "../ButtonSelect";
// // import Select from "react-select";
// import ButtonSelect from "../ButtonSelect";
const zIndexProps = {
menuPortalTarget: document.body,
styles: { menuPortal: (base: any) => ({ ...base, zIndex: 9999 }) },
};
// const zIndexProps = {
// menuPortalTarget: document.body,
// styles: { menuPortal: (base: any) => ({ ...base, zIndex: 9999 }) },
// };
const options: { label: string | JSX.Element, value: T.EquativeTense }[] = [{
label: "Present",
value: "present",
}, {
label: "Habitual",
value: "habitual",
}, {
label: "Subjunctive",
value: "subjunctive",
}, {
label: "Future",
value: "future",
}, {
label: "Past",
value: "past",
}, {
label: `"Would Be"`,
value: "wouldBe",
}, {
label: "Past Subjunctive",
value: "pastSubjunctive",
}, {
label: `"Would Have Been"`,
value: "wouldHaveBeen",
}];
// const options: { label: string | JSX.Element, value: T.EquativeTense }[] = [{
// label: "Present",
// value: "present",
// }, {
// label: "Habitual",
// value: "habitual",
// }, {
// label: "Subjunctive",
// value: "subjunctive",
// }, {
// label: "Future",
// value: "future",
// }, {
// label: "Past",
// value: "past",
// }, {
// label: `"Would Be"`,
// value: "wouldBe",
// }, {
// label: "Past Subjunctive",
// value: "pastSubjunctive",
// }, {
// label: `"Would Have Been"`,
// value: "wouldHaveBeen",
// }];
function EquativePicker({ equative, onChange, hideNegative }: {
equative: { tense: T.EquativeTense, negative: boolean },
onChange: (e: { tense: T.EquativeTense, negative: boolean }) => void,
hideNegative?: boolean,
}) {
function onTenseSelect(o: { value: T.EquativeTense } | null) {
const value = o?.value ? o.value : undefined;
if (!value) {
return;
}
onChange({
...equative,
tense: value,
});
}
function moveTense(dir: "forward" | "back") {
return () => {
const currIndex = options.findIndex(tn => tn.value === equative.tense)
if (currIndex === -1) {
console.error("error moving tense", dir);
return;
}
const newIndex = dir === "forward"
? ((currIndex + 1) % options.length)
: (currIndex === 0 ? (options.length - 1) : (currIndex - 1))
const newTense = options[newIndex];
onChange({
...equative,
tense: newTense.value,
});
};
}
function onPosNegSelect(value: "true" | "false") {
onChange({
...equative,
negative: value === "true",
});
}
return <div>
<div style={{ maxWidth: "300px", minWidth: "250px", margin: "0 auto" }}>
<div className="h5">Tense:</div>
<Select
isSearchable={false}
// for some reason can't use tOptions with find here;
value={options.find(o => o.value === equative.tense)}
onChange={onTenseSelect}
className="mb-2"
options={options}
{...zIndexProps}
/>
{<div className="d-flex flex-row justify-content-between align-items-center mt-3 mb-1" style={{ width: "100%" }}>
<div className="btn btn-light clickable" onClick={moveTense("back")}>
<i className="fas fa-chevron-left" />
</div>
{!hideNegative && <ButtonSelect
small
value={equative.negative.toString() as "true" | "false"}
options={[{
label: "Pos.",
value: "false",
}, {
label: "Neg.",
value: "true",
}]}
handleChange={onPosNegSelect}
/>}
<div onClick={moveTense("forward")} className="btn btn-light clickable">
<i className="fas fa-chevron-right" />
</div>
</div>}
</div>
</div>;
return <div>not here</div>;
// function onTenseSelect(o: { value: T.EquativeTense } | null) {
// const value = o?.value ? o.value : undefined;
// if (!value) {
// return;
// }
// onChange({
// ...equative,
// tense: value,
// });
// }
// function moveTense(dir: "forward" | "back") {
// return () => {
// const currIndex = options.findIndex(tn => tn.value === equative.tense)
// if (currIndex === -1) {
// console.error("error moving tense", dir);
// return;
// }
// const newIndex = dir === "forward"
// ? ((currIndex + 1) % options.length)
// : (currIndex === 0 ? (options.length - 1) : (currIndex - 1))
// const newTense = options[newIndex];
// onChange({
// ...equative,
// tense: newTense.value,
// });
// };
// }
// function onPosNegSelect(value: "true" | "false") {
// onChange({
// ...equative,
// negative: value === "true",
// });
// }
// return <div>
// <div style={{ maxWidth: "300px", minWidth: "250px", margin: "0 auto" }}>
// <div className="h5">Tense:</div>
// <Select
// isSearchable={false}
// // for some reason can't use tOptions with find here;
// value={options.find(o => o.value === equative.tense)}
// onChange={onTenseSelect}
// className="mb-2"
// options={options}
// {...zIndexProps}
// />
// {<div className="d-flex flex-row justify-content-between align-items-center mt-3 mb-1" style={{ width: "100%" }}>
// <div className="btn btn-light clickable" onClick={moveTense("back")}>
// <i className="fas fa-chevron-left" />
// </div>
// {!hideNegative && <ButtonSelect
// small
// value={equative.negative.toString() as "true" | "false"}
// options={[{
// label: "Pos.",
// value: "false",
// }, {
// label: "Neg.",
// value: "true",
// }]}
// handleChange={onPosNegSelect}
// />}
// <div onClick={moveTense("forward")} className="btn btn-light clickable">
// <i className="fas fa-chevron-right" />
// </div>
// </div>}
// </div>
// </div>;
}
export default EquativePicker;

View File

@ -1,10 +1,9 @@
// @ts-ignore
import Select from "react-select";
// import Select from "react-select";
import * as T from "../../types";
import ButtonSelect from "../ButtonSelect";
// import ButtonSelect from "../ButtonSelect";
import { isImperativeTense, isModalTense, isPerfectTense, isVerbTense } from "../../lib/type-predicates";
import useStickyState from "../../lib/useStickyState";
import { customStyles } from "../EntrySelect";
// import useStickyState from "../../lib/useStickyState";
// import { customStyles } from "../EntrySelect";
import {
VpsReducerAction
} from "./vps-reducer";
@ -43,15 +42,15 @@ const verbTenseOptions: { label: string | JSX.Element, value: T.VerbTense, formu
formula: "ba + simple past",
}];
function composeFormula(formula: string, prefix: "passive" | "ability"): string {
return formula.replace(/^perfective/, `${prefix} perfective`)
.replace(/^imperfective/, `${prefix} imperfective`)
.replace("continuous", `${prefix} continuous`)
.replace("simple", `${prefix} simple`)
.replace(/present$/, `${prefix} present`)
.replace(/subjunctive$/, `${prefix} subjunctive`)
.replace("past participle", `${prefix} past participle`);
}
// function composeFormula(formula: string, prefix: "passive" | "ability"): string {
// return formula.replace(/^perfective/, `${prefix} perfective`)
// .replace(/^imperfective/, `${prefix} imperfective`)
// .replace("continuous", `${prefix} continuous`)
// .replace("simple", `${prefix} simple`)
// .replace(/present$/, `${prefix} present`)
// .replace(/subjunctive$/, `${prefix} subjunctive`)
// .replace("past participle", `${prefix} past participle`);
// }
const perfectTenseOptions: { label: string | JSX.Element, value: T.PerfectTense, formula: string }[] = [{
label: "Present Perfect",
@ -125,175 +124,176 @@ function TensePicker(props: ({
onChange: (p: VpsReducerAction) => void,
mode: "charts" | "phrases" | "quiz",
}) {
const [showFormula, setShowFormula] = useStickyState<boolean>(false, "showFormula");
function onTenseSelect(o: { value: T.VerbTense | T.PerfectTense | T.ImperativeTense } | null) {
if ("vpsComplete" in props) return;
const tense = o?.value ? o.value : undefined;
props.onChange({
type: "set tense",
payload: tense,
});
}
function moveTense(dir: "forward" | "back") {
if ("vpsComplete" in props) return;
if (!props.vps.verb) return;
return () => {
// TODO: ABSTRACT THIS - SAFER
const tenses = props.vps.verb.tenseCategory === "perfect"
? perfectTenseOptions
: props.vps.verb.tenseCategory === "imperative"
? imperativeTenseOptions
: verbTenseOptions;
const currIndex = tenses.findIndex(tn => tn.value === props.vps.verb[
// TODO: ABSTRACT THIS? - SAFER
props.vps.verb.tenseCategory === "perfect"
? "perfectTense"
: props.vps.verb.tenseCategory === "imperative"
? "imperativeTense"
: "verbTense"
]);
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(payload: "true" | "false") {
if ("vpsComplete" in props) return;
props.onChange({
type: "set negativity",
payload,
});
}
function onTenseCategorySelect(payload: "basic" | "modal" | "perfect" | "imperative") {
if ("vpsComplete" in props) return;
props.onChange({
type: "set tense category",
payload,
});
}
const tOptions = ("vps" in props && (props.vps.verb?.tenseCategory === "perfect"))
? perfectTenseOptions
: ("vps" in props && (props.vps.verb?.tenseCategory === "imperative"))
? imperativeTenseOptions
: verbTenseOptions;
const showImperativeOption = ("vps" in props && props.vps.verb.voice === "active")
|| ("vpsComplete" in props && props.vpsComplete.verb.voice !== "active");
const inPassiveVoice = ("vps" in props && props.vps.verb.voice === "passive") || ("vpsComplete" in props && props.vpsComplete.verb.voice === "passive");;
const canHaveFormula = "vps" in props && props.mode !== "quiz";
return <div>
<div style={{ maxWidth: "300px", minWidth: "250px", margin: "0 auto" }}>
<div className="d-flex flex-row justify-content-between align-items-center">
<div className="h5">Verb Tense:</div>
{canHaveFormula && <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">
<ButtonSelect
small
value={"vpsComplete" in props
? getTenseCategory(props.vpsComplete.verb.tense)
: props.vps.verb.tenseCategory}
// @ts-ignore
options={showImperativeOption ? [{
label: "Basic",
value: "basic",
}, {
label: "Perfect",
value: "perfect",
}, {
label: "Ability",
value: "modal",
}, {
label: "Imperative",
value: "imperative",
}] : [{
label: "Basic",
value: "basic",
}, {
label: "Perfect",
value: "perfect",
}, {
label: "Ability",
value: "modal",
}].filter(x => !(inPassiveVoice && x.value === "modal"))}
handleChange={props.mode !== "quiz" ? onTenseCategorySelect : () => null}
/>
</div>}
{"vpsComplete" in props
? <div style={{ fontSize: "larger" }} className="mb-3">
{[...verbTenseOptions, ...perfectTenseOptions, ...imperativeTenseOptions].find(o => o.value === props.vpsComplete.verb.tense)?.label}
</div>
: <>
<Select
isSearchable={false}
// for some reason can't use tOptions with find here;
value={props.vps.verb && ([...verbTenseOptions, ...perfectTenseOptions, ...imperativeTenseOptions].find(o => o.value === props.vps.verb[
props.vps.verb.tenseCategory === "perfect"
? "perfectTense"
: props.vps.verb.tenseCategory === "imperative"
? "imperativeTense"
: "verbTense"
]))}
// @ts-ignore - gets messed up when using customStyles
onChange={onTenseSelect}
className="mb-2"
options={tOptions}
styles={customStyles}
/>
</>}
{"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")}>
<i className="fas fa-chevron-left" />
</div>
{props.mode === "phrases" && <ButtonSelect
small
value={props.vps.verb.negative.toString() as "true" | "false"}
options={[{
label: "Pos.",
value: "false",
}, {
label: "Neg.",
value: "true",
}]}
handleChange={onPosNegSelect}
/>}
<div onClick={moveTense("forward")} className="btn btn-light clickable">
<i className="fas fa-chevron-right" />
</div>
</div>}
{(canHaveFormula && showFormula) && (() => {
// 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"
]);
const formula = !curr
? ""
: (props.vps.verb.tenseCategory === "modal")
? composeFormula(curr.formula, "ability")
: (props.vps.verb.voice === "passive")
? composeFormula(curr.formula, "passive")
: curr.formula;
if (curr && "formula" in curr) {
return <div className="mb-2" style={{ width: "250px", overflowY: "auto" }}>
<samp>{formula}</samp>
</div>
}
})()}
</div>
</div>;
return <div>not here</div>
// const [showFormula, setShowFormula] = useStickyState<boolean>(false, "showFormula");
// function onTenseSelect(o: { value: T.VerbTense | T.PerfectTense | T.ImperativeTense } | null) {
// if ("vpsComplete" in props) return;
// const tense = o?.value ? o.value : undefined;
// props.onChange({
// type: "set tense",
// payload: tense,
// });
// }
// function moveTense(dir: "forward" | "back") {
// if ("vpsComplete" in props) return;
// if (!props.vps.verb) return;
// return () => {
// // TODO: ABSTRACT THIS - SAFER
// const tenses = props.vps.verb.tenseCategory === "perfect"
// ? perfectTenseOptions
// : props.vps.verb.tenseCategory === "imperative"
// ? imperativeTenseOptions
// : verbTenseOptions;
// const currIndex = tenses.findIndex(tn => tn.value === props.vps.verb[
// // TODO: ABSTRACT THIS? - SAFER
// props.vps.verb.tenseCategory === "perfect"
// ? "perfectTense"
// : props.vps.verb.tenseCategory === "imperative"
// ? "imperativeTense"
// : "verbTense"
// ]);
// 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(payload: "true" | "false") {
// if ("vpsComplete" in props) return;
// props.onChange({
// type: "set negativity",
// payload,
// });
// }
// function onTenseCategorySelect(payload: "basic" | "modal" | "perfect" | "imperative") {
// if ("vpsComplete" in props) return;
// props.onChange({
// type: "set tense category",
// payload,
// });
// }
// const tOptions = ("vps" in props && (props.vps.verb?.tenseCategory === "perfect"))
// ? perfectTenseOptions
// : ("vps" in props && (props.vps.verb?.tenseCategory === "imperative"))
// ? imperativeTenseOptions
// : verbTenseOptions;
// const showImperativeOption = ("vps" in props && props.vps.verb.voice === "active")
// || ("vpsComplete" in props && props.vpsComplete.verb.voice !== "active");
// const inPassiveVoice = ("vps" in props && props.vps.verb.voice === "passive") || ("vpsComplete" in props && props.vpsComplete.verb.voice === "passive");;
// const canHaveFormula = "vps" in props && props.mode !== "quiz";
// return <div>
// <div style={{ maxWidth: "300px", minWidth: "250px", margin: "0 auto" }}>
// <div className="d-flex flex-row justify-content-between align-items-center">
// <div className="h5">Verb Tense:</div>
// {canHaveFormula && <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">
// <ButtonSelect
// small
// value={"vpsComplete" in props
// ? getTenseCategory(props.vpsComplete.verb.tense)
// : props.vps.verb.tenseCategory}
// // @ts-ignore
// options={showImperativeOption ? [{
// label: "Basic",
// value: "basic",
// }, {
// label: "Perfect",
// value: "perfect",
// }, {
// label: "Ability",
// value: "modal",
// }, {
// label: "Imperative",
// value: "imperative",
// }] : [{
// label: "Basic",
// value: "basic",
// }, {
// label: "Perfect",
// value: "perfect",
// }, {
// label: "Ability",
// value: "modal",
// }].filter(x => !(inPassiveVoice && x.value === "modal"))}
// handleChange={props.mode !== "quiz" ? onTenseCategorySelect : () => null}
// />
// </div>}
// {"vpsComplete" in props
// ? <div style={{ fontSize: "larger" }} className="mb-3">
// {[...verbTenseOptions, ...perfectTenseOptions, ...imperativeTenseOptions].find(o => o.value === props.vpsComplete.verb.tense)?.label}
// </div>
// : <>
// <Select
// isSearchable={false}
// // for some reason can't use tOptions with find here;
// value={props.vps.verb && ([...verbTenseOptions, ...perfectTenseOptions, ...imperativeTenseOptions].find(o => o.value === props.vps.verb[
// props.vps.verb.tenseCategory === "perfect"
// ? "perfectTense"
// : props.vps.verb.tenseCategory === "imperative"
// ? "imperativeTense"
// : "verbTense"
// ]))}
// // @ts-ignore - gets messed up when using customStyles
// onChange={onTenseSelect}
// className="mb-2"
// options={tOptions}
// styles={customStyles}
// />
// </>}
// {"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")}>
// <i className="fas fa-chevron-left" />
// </div>
// {props.mode === "phrases" && <ButtonSelect
// small
// value={props.vps.verb.negative.toString() as "true" | "false"}
// options={[{
// label: "Pos.",
// value: "false",
// }, {
// label: "Neg.",
// value: "true",
// }]}
// handleChange={onPosNegSelect}
// />}
// <div onClick={moveTense("forward")} className="btn btn-light clickable">
// <i className="fas fa-chevron-right" />
// </div>
// </div>}
// {(canHaveFormula && showFormula) && (() => {
// // 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"
// ]);
// const formula = !curr
// ? ""
// : (props.vps.verb.tenseCategory === "modal")
// ? composeFormula(curr.formula, "ability")
// : (props.vps.verb.voice === "passive")
// ? composeFormula(curr.formula, "passive")
// : curr.formula;
// if (curr && "formula" in curr) {
// return <div className="mb-2" style={{ width: "250px", overflowY: "auto" }}>
// <samp>{formula}</samp>
// </div>
// }
// })()}
// </div>
// </div>;
}
export default TensePicker;

View File

@ -1303,7 +1303,7 @@
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.0.tgz#f580f9beb67176fa57aae70b08ed510e1b18980f"
integrity sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==
"@emotion/react@^11.1.1", "@emotion/react@^11.8.1":
"@emotion/react@^11.8.1":
version "11.10.4"
resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.10.4.tgz#9dc6bccbda5d70ff68fdb204746c0e8b13a79199"
integrity sha512-j0AkMpr6BL8gldJZ6XQsQ8DnS9TxEQu1R+OGmDZiWjBAJtCcbt0tS3I/YffoqHXxH6MjgI7KdMbYKw3MEiU9eA==
@ -9320,7 +9320,7 @@ prop-types-extra@^1.1.0:
react-is "^16.3.2"
warning "^4.0.0"
prop-types@^15.5.8, prop-types@^15.6.0:
prop-types@^15.6.0:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@ -9577,13 +9577,6 @@ react-error-overlay@^6.0.9:
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a"
integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==
react-input-autosize@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-3.0.0.tgz#6b5898c790d4478d69420b55441fcc31d5c50a85"
integrity sha512-nL9uS7jEs/zu8sqwFE5MAPx6pPkNAriACQ2rGLlqmKr2sPGtN7TXTyDdQt4lbNXVx7Uzadb40x8qotIuru6Rhg==
dependencies:
prop-types "^15.5.8"
react-is@^16.13.1, react-is@^16.3.2, react-is@^16.7.0, react-is@^16.8.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
@ -9697,19 +9690,6 @@ react-select@*:
prop-types "^15.6.0"
react-transition-group "^4.3.0"
react-select@^4.3.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/react-select/-/react-select-4.3.1.tgz#389fc07c9bc7cf7d3c377b7a05ea18cd7399cb81"
integrity sha512-HBBd0dYwkF5aZk1zP81Wx5UsLIIT2lSvAY2JiJo199LjoLHoivjn9//KsmvQMEFGNhe58xyuOITjfxKCcGc62Q==
dependencies:
"@babel/runtime" "^7.12.0"
"@emotion/cache" "^11.4.0"
"@emotion/react" "^11.1.1"
memoize-one "^5.0.0"
prop-types "^15.6.0"
react-input-autosize "^3.0.0"
react-transition-group "^4.3.0"
react-transition-group@^4.3.0:
version "4.4.5"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1"