diff --git a/package.json b/package.json index 3c0806d..e61f940 100644 --- a/package.json +++ b/package.json @@ -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" }, diff --git a/rollup.config.js b/rollup.config.js deleted file mode 100644 index 1b13ec1..0000000 --- a/rollup.config.js +++ /dev/null @@ -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(), - ] -} \ No newline at end of file diff --git a/src/components/EntrySelect.tsx b/src/components/EntrySelect.tsx index ab41d00..9514fc0 100644 --- a/src/components/EntrySelect.tsx +++ b/src/components/EntrySelect.tsx @@ -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(props: { entryFeeder: T.EntryFeederSingleType, @@ -38,79 +36,80 @@ function EntrySelect(props: { opts: T.TextOptions, style?: StyleHTMLAttributes, }) { - 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
- -
; - } - 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
- +//
} export function SandwichSelect(props: { @@ -121,62 +120,63 @@ export function SandwichSelect(props: { opts: T.TextOptions, style?: StyleHTMLAttributes, }) { - 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
-
Sandwich Base
- +//
} -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; \ No newline at end of file diff --git a/src/components/ep-explorer/EquativePicker.tsx b/src/components/ep-explorer/EquativePicker.tsx index de03c92..30717a2 100644 --- a/src/components/ep-explorer/EquativePicker.tsx +++ b/src/components/ep-explorer/EquativePicker.tsx @@ -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
-
-
Tense:
- o.value === equative.tense)} + // onChange={onTenseSelect} + // className="mb-2" + // options={options} + // {...zIndexProps} + // /> + // {
+ //
+ // + //
+ // {!hideNegative && } + //
+ // + //
+ //
} + //
+ //
; } export default EquativePicker; \ No newline at end of file diff --git a/src/components/vp-explorer/TensePicker.tsx b/src/components/vp-explorer/TensePicker.tsx index 513c005..eeb5a63 100644 --- a/src/components/vp-explorer/TensePicker.tsx +++ b/src/components/vp-explorer/TensePicker.tsx @@ -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(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
-
-
-
Verb Tense:
- {canHaveFormula &&
setShowFormula(x => !x)}> - 🧪 {!showFormula ? "Show" : "Hide"} Formula -
} -
- {("vpsComplete" in props || props.vps.verb) &&
- !(inPassiveVoice && x.value === "modal"))} - handleChange={props.mode !== "quiz" ? onTenseCategorySelect : () => null} - /> -
} - {"vpsComplete" in props - ?
- {[...verbTenseOptions, ...perfectTenseOptions, ...imperativeTenseOptions].find(o => o.value === props.vpsComplete.verb.tense)?.label} -
- : <> - 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") &&
+//
+// +//
+// {props.mode === "phrases" && } +//
+// +//
+//
} +// {(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
+// {formula} +//
+// } +// })()} +//
+//
; } export default TensePicker; diff --git a/yarn.lock b/yarn.lock index 1c5e3fa..c6a8ca4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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"