better
This commit is contained in:
parent
e9fd455037
commit
7e3d644380
|
@ -3,9 +3,10 @@
|
|||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@formkit/auto-animate": "^1.0.0-beta.1",
|
||||
"@fortawesome/fontawesome-free": "^5.15.4",
|
||||
"@lingdocs/lingdocs-main": "^0.3.1",
|
||||
"@lingdocs/pashto-inflector": "^2.6.2",
|
||||
"@lingdocs/pashto-inflector": "^2.6.4",
|
||||
"@testing-library/jest-dom": "^5.11.4",
|
||||
"@testing-library/react": "^11.1.0",
|
||||
"@testing-library/user-event": "^12.1.10",
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
import {
|
||||
Types as T,
|
||||
NPPicker,
|
||||
} from "@lingdocs/pashto-inflector";
|
||||
import { useState } from "react";
|
||||
import PhraseDiagram from "./phrase-diagram/PhraseDiagram";
|
||||
import entryFeeder from "../lib/entry-feeder";
|
||||
|
||||
function NPPlayground({ opts, npIn }: {
|
||||
opts: T.TextOptions,
|
||||
npIn: T.NPSelection | undefined,
|
||||
}) {
|
||||
const [np, setNp] = useState<T.NPSelection | undefined>(npIn);
|
||||
return <div className="d-flex flex-column align-items-center">
|
||||
<div style={{ maxWidth: "225px", marginBottom: "2rem" }}>
|
||||
<NPPicker
|
||||
opts={opts}
|
||||
np={np}
|
||||
onChange={setNp}
|
||||
entryFeeder={entryFeeder}
|
||||
role="subject"
|
||||
counterPart={undefined}
|
||||
phraseIsComplete={false}
|
||||
/>
|
||||
</div>
|
||||
{np && <PhraseDiagram opts={opts}>{[
|
||||
{ type: "NP", block: np },
|
||||
]}</PhraseDiagram>}
|
||||
</div>
|
||||
}
|
||||
|
||||
export default NPPlayground;
|
|
@ -1,9 +1,16 @@
|
|||
import {
|
||||
Types as T,
|
||||
NPPicker,
|
||||
APPicker,
|
||||
} from "@lingdocs/pashto-inflector";
|
||||
import {
|
||||
useEffect,
|
||||
useRef,
|
||||
} from "react";
|
||||
import { useState } from "react";
|
||||
import PhraseDiagram from "./PhraseDiagram";
|
||||
import NPPlayground from "../NPPlayground";
|
||||
import entryFeeder from "../../lib/entry-feeder";
|
||||
import autoAnimate from "@formkit/auto-animate";
|
||||
|
||||
export function EditIcon() {
|
||||
return <i className="fas fa-edit" />;
|
||||
|
@ -13,19 +20,64 @@ function EditablePhraseDiagram({ opts, children }: {
|
|||
opts: T.TextOptions,
|
||||
children: BlockInput[],
|
||||
}) {
|
||||
const np = children[0].block;
|
||||
const block = children[0];
|
||||
const parent = useRef<HTMLDivElement>(null);
|
||||
useEffect(() => {
|
||||
parent.current && autoAnimate(parent.current)
|
||||
}, [parent]);
|
||||
const [editing, setEditing] = useState<boolean>(false);
|
||||
const [edited, setEdited] = useState<{
|
||||
type: "NP",
|
||||
block: T.NPSelection | undefined,
|
||||
} | {
|
||||
type: "AP",
|
||||
block: T.APSelection | undefined,
|
||||
}>(block);
|
||||
if (children.length === 0) return null;
|
||||
function handleNPChange(np: T.NPSelection | undefined) {
|
||||
setEdited({ type: "NP", block: np });
|
||||
}
|
||||
function handleAPChange(ap: T.APSelection | undefined) {
|
||||
setEdited({ type: "AP", block: ap });
|
||||
}
|
||||
function handleReset() {
|
||||
setEdited(block);
|
||||
setEditing(false);
|
||||
}
|
||||
return <div>
|
||||
<div className="text-right clickable" onClick={() => setEditing(e => !e)}>
|
||||
<div
|
||||
className="text-right clickable"
|
||||
onClick={editing ? handleReset : () => setEditing(true)}
|
||||
>
|
||||
{!editing ? <EditIcon /> : <i className="fas fa-undo" />}
|
||||
</div>
|
||||
<div>
|
||||
{editing
|
||||
? <NPPlayground opts={opts} npIn={np} />
|
||||
: <PhraseDiagram opts={opts}>{[
|
||||
{ type: "NP", block: np },
|
||||
]}</PhraseDiagram>}
|
||||
<div ref={parent} className="d-flex flex-column align-items-center">
|
||||
{editing && <div style={{ maxWidth: "225px", marginBottom: "2rem" }}>
|
||||
{edited.type === "NP"
|
||||
? <NPPicker
|
||||
opts={opts}
|
||||
np={edited.block}
|
||||
onChange={handleNPChange}
|
||||
entryFeeder={entryFeeder}
|
||||
role="subject"
|
||||
counterPart={undefined}
|
||||
phraseIsComplete={false}
|
||||
/>
|
||||
: <APPicker
|
||||
opts={opts}
|
||||
AP={edited.block}
|
||||
onChange={handleAPChange}
|
||||
entryFeeder={entryFeeder}
|
||||
phraseIsComplete={false}
|
||||
cantClear
|
||||
onRemove={() => null}
|
||||
/>
|
||||
}
|
||||
</div>}
|
||||
{edited.block
|
||||
&& <PhraseDiagram opts={opts}>
|
||||
{[edited] as BlockInput[]}
|
||||
</PhraseDiagram>}
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import {
|
|||
renderNPSelection,
|
||||
Types as T,
|
||||
getEnglishFromRendered,
|
||||
renderAPSelection,
|
||||
} from "@lingdocs/pashto-inflector";
|
||||
import classNames from "classnames";
|
||||
|
||||
|
@ -22,13 +23,51 @@ function Block({ opts, children }: {
|
|||
opts: T.TextOptions,
|
||||
children: BlockInput,
|
||||
}) {
|
||||
// const possesor = children.block.possesor;
|
||||
if (children.type === "NP") {
|
||||
const rendered = renderNPSelection(children.block, false, false, "subject", "none");
|
||||
const english = getEnglishFromRendered(rendered)
|
||||
return <div className="text-center mb-2">
|
||||
<NP opts={opts} english={english}>{rendered}</NP>
|
||||
</div>;
|
||||
}
|
||||
const rendered = renderAPSelection(children.block);
|
||||
const english = getEnglishFromRendered(rendered)
|
||||
return <div className="text-center mb-2">
|
||||
<AP opts={opts} english={english}>{rendered}</AP>
|
||||
</div>;
|
||||
}
|
||||
|
||||
function AP({ opts, children, english }: {
|
||||
opts: T.TextOptions,
|
||||
children: T.Rendered<T.APSelection>,
|
||||
english?: string,
|
||||
}) {
|
||||
const ap = children;
|
||||
if (ap.type === "adverb") {
|
||||
return <div>
|
||||
<div
|
||||
className={classNames("d-flex flex-row justify-content-center align-items-center")}
|
||||
style={{
|
||||
border: "2px solid black",
|
||||
padding: "1rem",
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
{ap.ps[0].f}
|
||||
</div>
|
||||
<div>AP</div>
|
||||
{english && <div className="small text-muted text-center" style={{
|
||||
// TODO: find a better way to keep this limited to the width of the div above
|
||||
// don't let this make the div above expand
|
||||
margin: "0 auto",
|
||||
maxWidth: "300px",
|
||||
}}>{english}</div>}
|
||||
</div>;
|
||||
}
|
||||
return <div>
|
||||
Will implement sandwich
|
||||
</div>;
|
||||
}
|
||||
|
||||
function NP({ opts, children, inside, english }: {
|
||||
opts: T.TextOptions,
|
||||
|
|
|
@ -21,6 +21,8 @@ import * as equativeExplorer from "!babel-loader!@lingdocs/mdx-loader!./equative
|
|||
|
||||
// @ts-ignore
|
||||
import * as NPIntro from "!babel-loader!@lingdocs/mdx-loader!./phrase-structure/np.mdx";
|
||||
// @ts-ignore
|
||||
import * as APIntro from "!babel-loader!@lingdocs/mdx-loader!./phrase-structure/ap.mdx";
|
||||
|
||||
// @ts-ignore
|
||||
import * as nounsGender from "!babel-loader!@lingdocs/mdx-loader!./nouns/nouns-gender.mdx";
|
||||
|
@ -105,6 +107,10 @@ const contentTree = [
|
|||
import: NPIntro,
|
||||
slug: "np",
|
||||
},
|
||||
{
|
||||
import: APIntro,
|
||||
slug: "ap",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
@ -2,4 +2,48 @@
|
|||
title: APs
|
||||
---
|
||||
|
||||
AP page here
|
||||
import {
|
||||
defaultTextOptions as opts,
|
||||
InlinePs,
|
||||
Examples,
|
||||
} from "@lingdocs/pashto-inflector";
|
||||
import psmd from "../../lib/psmd";
|
||||
import Link from "../../components/Link";
|
||||
import EditablePhraseDiagram, {
|
||||
EditIcon,
|
||||
} from "../../components/phrase-diagram/EditablePhraseDiagram";
|
||||
|
||||
Another building block we have in Pashto phrases in the **AP (Adverb Phrase)**. Adverb Phrases are used to give more information about the phrase in terms of time, manner, place, degree, etc.
|
||||
|
||||
An AP is either:
|
||||
|
||||
- an adverb, or
|
||||
- a sandwich
|
||||
|
||||
### Adverb
|
||||
|
||||
An adverb is a word or expression that modifies the time, manner, place, etc. of a phrase.
|
||||
|
||||
<EditablePhraseDiagram opts={opts}>{[
|
||||
{
|
||||
type: "AP",
|
||||
block: {
|
||||
type: "adverb",
|
||||
entry: {"ts":1527815160,"i":2394,"p":"پرون","f":"paroon","g":"paroon","e":"yesterday","c":"adv."},
|
||||
},
|
||||
},
|
||||
]}</EditablePhraseDiagram>
|
||||
|
||||
<EditablePhraseDiagram opts={opts}>{[
|
||||
{
|
||||
type: "AP",
|
||||
block: {
|
||||
type: "adverb",
|
||||
entry: {"ts":1527819967,"i":5428,"p":"خامخا","f":"khaamakhaa","g":"khaamakhaa","e":"definitely, for sure, whether someone wants or not, willy-nilly (this last use more in Urdu)","c":"adv."},
|
||||
},
|
||||
},
|
||||
]}</EditablePhraseDiagram>
|
||||
|
||||
### Sandwich
|
||||
|
||||
Coming soon...
|
|
@ -12,7 +12,7 @@ import Link from "../../components/Link";
|
|||
import EditablePhraseDiagram, {
|
||||
EditIcon,
|
||||
} from "../../components/phrase-diagram/EditablePhraseDiagram";
|
||||
import NPPlayground from "../../components/NPPlayground";
|
||||
// import NPPlayground from "../../components/NPPlayground";
|
||||
|
||||
Pashto phrases are built with a basic **building blocks** 🧱 like NPs, APs, verbs, and equatives. We can think of phrases in Pashto as a line of blocks like this:
|
||||
|
||||
|
@ -409,8 +409,8 @@ An **NP** is one of the following:
|
|||
|
||||
Notice how NPs can contain other NPs, and therefore go on foreeeever. So you could have like 50 words packed together and it would all be **one single NP**, **one building block** in a sentence.
|
||||
|
||||
## NP Playground
|
||||
<!-- ## NP Playground
|
||||
|
||||
Now try making your own NPs from scratch! 👩🍳 See if you can make really big ones like "hitting my good old friend's brother's father's big dog."
|
||||
|
||||
<NPPlayground opts={opts} />
|
||||
<NPPlayground opts={opts} /> -->
|
||||
|
|
|
@ -4,4 +4,10 @@ type Pronoun = {
|
|||
person: import("@lingdocs/pashto-inflector").Types.Person,
|
||||
};
|
||||
|
||||
type BlockInput = { type: "NP", block: T.NPSelection };
|
||||
type BlockInput = {
|
||||
type: "NP",
|
||||
block: import("@lingdocs/pashto-inflector").Types.NPSelection,
|
||||
} | {
|
||||
type: "AP",
|
||||
block: import("@lingdocs/pashto-inflector").Types.APSelection,
|
||||
};
|
||||
|
|
14
yarn.lock
14
yarn.lock
|
@ -1695,13 +1695,12 @@
|
|||
rambda "^6.7.0"
|
||||
react-select "^5.2.2"
|
||||
|
||||
"@lingdocs/pashto-inflector@^2.6.2":
|
||||
version "2.6.2"
|
||||
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-2.6.2.tgz#41c6a18a67aa9dff8ade2fd49ad8b27d04ecb4f8"
|
||||
integrity sha512-GSiJ7FFoDEDIfDcPv10SienHYQr/8lRmBP6fbwDV2vFVf9vJ4+nywuhFmU0JuBL2HILG/e6CQ3tvQZvoquopCg==
|
||||
"@lingdocs/pashto-inflector@^2.6.4":
|
||||
version "2.6.5"
|
||||
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-2.6.5.tgz#9cd8efd14d48d0a9aa9ff8439b2bdc135a855f57"
|
||||
integrity sha512-y1prO4ASg1P2v5960twoYD2NOfN4P6vc9cM2/QqMIHQX7TkXwzFnjKKu9MD3dCOH0FPOv1V6NAEgbBMJGJa1Pw==
|
||||
dependencies:
|
||||
"@formkit/auto-animate" "^1.0.0-beta.1"
|
||||
assert-never "^1.2.1"
|
||||
classnames "^2.2.6"
|
||||
jsurl2 "^2.1.0"
|
||||
lz-string "^1.4.4"
|
||||
|
@ -2930,11 +2929,6 @@ asn1@~0.2.3:
|
|||
dependencies:
|
||||
safer-buffer "~2.1.0"
|
||||
|
||||
assert-never@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/assert-never/-/assert-never-1.2.1.tgz#11f0e363bf146205fb08193b5c7b90f4d1cf44fe"
|
||||
integrity sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==
|
||||
|
||||
assert-plus@1.0.0, assert-plus@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
|
||||
|
|
Loading…
Reference in New Issue