From 892bc626034cebecaa35a9987b91452b7c092774 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Heimb=C3=BCrger?= Date: Thu, 8 Aug 2019 23:32:59 +0100 Subject: [PATCH 1/8] Clean up code --- src/MathFieldComponent.tsx | 79 ++++++++++++-------------------------- src/index.ts | 2 +- 2 files changed, 26 insertions(+), 55 deletions(-) diff --git a/src/MathFieldComponent.tsx b/src/MathFieldComponent.tsx index 96d0b96..f246ca2 100644 --- a/src/MathFieldComponent.tsx +++ b/src/MathFieldComponent.tsx @@ -6,13 +6,11 @@ import { makeMathField } from 'mathlive'; export interface Props { latex: string; onChange?: (latex: string) => void; - onBlur?: () => void; - onKeystroke?: (ev: KeyboardEvent) => void; /** * The raw options of mathlive's makeMathField. * */ - mathFieldOptions?: MathFieldConfig; + mathFieldConfig?: MathFieldConfig; /** * The mathfield object returned by makeMathField. @@ -20,61 +18,34 @@ export interface Props { mathFieldRef?: (mathfield: MathField) => void; } +export function combineConfig(props: Props): MathFieldConfig { + const combinedConfiguration: MathFieldConfig = { + ...props.mathFieldConfig + }; + + const { onChange } = props; + + if (onChange) { + if (props.mathFieldConfig && props.mathFieldConfig.onContentDidChange) { + const fromConfig = props.mathFieldConfig.onContentDidChange; + combinedConfiguration.onContentDidChange = mf => { + onChange(mf.$latex()); + fromConfig(mf); + }; + } else { + combinedConfiguration.onContentDidChange = mf => onChange(mf.$latex()); + } + } + + return combinedConfiguration; +} + /** A react-control that hosts a mathlive-mathfield in it. */ export class MathFieldComponent extends React.Component { private insertElement: HTMLElement | null = null; - private readonly combinedOptions: MathFieldConfig; + private readonly combinedConfiguration = combineConfig(this.props); private mathField: MathField | undefined; - constructor(props: Props) { - super(props); - - this.combinedOptions = { - ...props.mathFieldOptions - }; - - const { onChange, onBlur, onKeystroke } = this.props; - - if (onChange) { - if (props.mathFieldOptions && props.mathFieldOptions.onContentDidChange) { - const fromOptions = props.mathFieldOptions.onContentDidChange; - this.combinedOptions.onContentDidChange = mf => { - onChange(mf.$latex()); - fromOptions(mf); - }; - } else { - this.combinedOptions.onContentDidChange = mf => onChange(mf.$latex()); - } - } - - if (onBlur) { - if (props.mathFieldOptions && props.mathFieldOptions.onBlur) { - const fromOptions = props.mathFieldOptions.onBlur; - this.combinedOptions.onBlur = mf => { - onBlur(); - fromOptions(mf); - }; - } else { - this.combinedOptions.onBlur = onBlur; - } - } - - if (onKeystroke) { - if (props.mathFieldOptions && props.mathFieldOptions.onKeystroke) { - const fromOptions = props.mathFieldOptions.onKeystroke; - this.combinedOptions.onKeystroke = (mf, ks, ev) => { - onKeystroke(ev); - return fromOptions(mf, ks, ev); - }; - } else { - this.combinedOptions.onKeystroke = (mf, ks, ev) => { - onKeystroke(ev); - return true; - } - } - } - } - componentWillReceiveProps(newProps: Props) { if (!this.mathField) { throw new Error("Component was not correctly initialized."); @@ -97,7 +68,7 @@ export class MathFieldComponent extends React.Component { throw new Error("React did apparently not mount the insert point correctly."); } - this.mathField = makeMathField(this.insertElement, this.combinedOptions); + this.mathField = makeMathField(this.insertElement, this.combinedConfiguration); this.mathField.$latex(this.props.latex, { suppressChangeNotifications: true }); if (this.props.mathFieldRef) { diff --git a/src/index.ts b/src/index.ts index dcc900b..4aeaeb1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1 @@ -export * from './MathFieldComponent'; \ No newline at end of file +export { MathFieldComponent, Props as MathFieldComponentProps } from './MathFieldComponent'; \ No newline at end of file From 1a6905814bb0e051d66322ac00c4879efe4cc8fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Heimb=C3=BCrger?= Date: Thu, 8 Aug 2019 23:33:16 +0100 Subject: [PATCH 2/8] Increase test coverage --- src/MathFieldComponent.test.tsx | 50 +++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/src/MathFieldComponent.test.tsx b/src/MathFieldComponent.test.tsx index 3ea0ea3..cc00019 100644 --- a/src/MathFieldComponent.test.tsx +++ b/src/MathFieldComponent.test.tsx @@ -5,10 +5,33 @@ import { cleanup, waitForElement, } from '@testing-library/react'; -import { MathFieldComponent } from './MathFieldComponent'; +import "mathlive"; +import { MathFieldComponent, combineConfig } from './MathFieldComponent'; afterEach(cleanup); +describe("combineConfig", () => { + it(" combines onChange and native onContentDidChange handlers", () => { + let value1: string | undefined, + value2: string | undefined; + + const combinedConfig = combineConfig({ + latex: "fubar", + onChange: v => value1 = v, + mathFieldConfig: { + onContentDidChange: mf => value2 = mf.$latex(), + }, + }); + + combinedConfig.onContentDidChange!({ + $latex: () => "bar", + }); + + expect(value1).toBe("bar"); + expect(value2).toBe("bar"); + }); +}); + describe("MathFieldComponent", () => { it(" mounts mathfield", () => { const mountingResult = render( @@ -22,7 +45,7 @@ describe("MathFieldComponent", () => { it(" internal mathfield yields correct latex", () => { let mathField: any; - const mountingResult = render( + render( mathField = mf} latex="fubar" @@ -31,7 +54,7 @@ describe("MathFieldComponent", () => { expect(mathField.$latex()).toBe("fubar"); }); - it(" onChange reacts to direct mathfield interaction", () => { + it(" reacts to direct mathfield interaction", () => { let value = "foo"; let mathField: any; render( @@ -48,8 +71,8 @@ describe("MathFieldComponent", () => { expect(value).toBe("bar"); expect(mathField.$latex()).toBe("bar"); }); - - it(" accept changed props", () => { + + it(" accepts changed props", () => { class Container extends React.Component<{}, { value: string }> { public state = { value: "foo" }; public mathField: any; @@ -72,4 +95,21 @@ describe("MathFieldComponent", () => { container.forceUpdate(); expect(mathField.$latex()).toBe("bar"); }); + + test("invalidly created instances throw correct errors", () => { + const mathFieldComponent = new MathFieldComponent({ latex: "fubar" }); + try { + mathFieldComponent.componentWillReceiveProps({ latex: "baz" }); + fail("The previous line should have thrown."); + } catch (e) { + expect(e.message).toBe("Component was not correctly initialized."); + } + + try { + mathFieldComponent.componentDidMount(); + fail("The previous line should have thrown."); + } catch (e) { + expect(e.message).toBe("React did apparently not mount the insert point correctly."); + } + }); }); \ No newline at end of file From 71a1ee38245dd1be9c860e11f4ec524b8f737c0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Heimb=C3=BCrger?= Date: Thu, 8 Aug 2019 23:33:53 +0100 Subject: [PATCH 3/8] Update dependencies --- package-lock.json | 76 +++++++++++++++++++++++++++++------------------ package.json | 6 ++-- 2 files changed, 50 insertions(+), 32 deletions(-) diff --git a/package-lock.json b/package-lock.json index dc3f78a..361c120 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "react-mathlive", - "version": "1.3.1", + "version": "1.3.2", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -552,9 +552,9 @@ "dev": true }, "acorn-globals": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.2.tgz", - "integrity": "sha512-BbzvZhVtZP+Bs1J1HcwrQe8ycfO0wStkSGxuul3He3GkHOIZ6eTqOkPuw9IP1X3+IkOo4wiJmwkobzXYz4wewQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.3.tgz", + "integrity": "sha512-vkR40VwS2SYO98AIeFvzWWh+xyc2qi9s7OoXSFEGIP/rOJKzjnhykaZJNnHdoq4BL2gGxI5EZOU16z896EYnOQ==", "dev": true, "requires": { "acorn": "^6.0.1", @@ -701,9 +701,9 @@ "dev": true }, "async-limiter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", "dev": true }, "asynckit": { @@ -2280,9 +2280,9 @@ "dev": true }, "graceful-fs": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", - "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", + "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", "dev": true }, "growl": { @@ -2385,10 +2385,13 @@ } }, "hosted-git-info": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", - "dev": true + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.2.tgz", + "integrity": "sha512-CyjlXII6LMsPMyUzxpTt8fzh5QwzGqPmQXgY/Jyf4Zfp27t/FvfhwoE/8laaMUcMy816CkWF20I7NeQhwwY88w==", + "dev": true, + "requires": { + "lru-cache": "^5.1.1" + } }, "html-encoding-sniffer": { "version": "1.0.2", @@ -2771,13 +2774,13 @@ } }, "jest": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-24.8.0.tgz", - "integrity": "sha512-o0HM90RKFRNWmAWvlyV8i5jGZ97pFwkeVoGvPW1EtLTgJc2+jcuqcbbqcSZLE/3f2S5pt0y2ZBETuhpWNl1Reg==", + "version": "24.7.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-24.7.1.tgz", + "integrity": "sha512-AbvRar5r++izmqo5gdbAjTeA6uNRGoNRuj5vHB0OnDXo2DXWZJVuaObiGgtlvhKb+cWy2oYbQSfxv7Q7GjnAtA==", "dev": true, "requires": { "import-local": "^2.0.0", - "jest-cli": "^24.8.0" + "jest-cli": "^24.7.1" }, "dependencies": { "jest-cli": { @@ -3397,6 +3400,15 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, "make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", @@ -3637,9 +3649,9 @@ "dev": true }, "node-notifier": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.0.tgz", - "integrity": "sha512-SUDEb+o71XR5lXSTyivXd9J7fCloE3SyP4lSgt3lU2oSANiox+SxlNRGPjDKrwU1YN3ix2KN/VGGCg0t01rttQ==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.1.tgz", + "integrity": "sha512-p52B+onAEHKW1OF9MGO/S7k/ahGEHfhP5/tvwYzog/5XLYOd8ZuD6vdNZdUuWMONRnKPneXV43v3s6Snx1wsCQ==", "dev": true, "requires": { "growly": "^1.3.0", @@ -4006,13 +4018,13 @@ "dev": true }, "prompts": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.1.0.tgz", - "integrity": "sha512-+x5TozgqYdOwWsQFZizE/Tra3fKvAoy037kOyU6cgz84n8f6zxngLOV4O32kTwt9FcLCxAqw0P/c8rOr9y+Gfg==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.2.1.tgz", + "integrity": "sha512-VObPvJiWPhpZI6C5m60XOzTfnYg/xc/an+r9VYymj9WJW3B/DIH+REzjpAACPf8brwPeP+7vz3bIim3S+AaMjw==", "dev": true, "requires": { - "kleur": "^3.0.2", - "sisteransi": "^1.0.0" + "kleur": "^3.0.3", + "sisteransi": "^1.0.3" } }, "prop-types": { @@ -4404,9 +4416,9 @@ "dev": true }, "sisteransi": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.2.tgz", - "integrity": "sha512-ZcYcZcT69nSLAR2oLN2JwNmLkJEKGooFMCdvOkFrToUt/WfcRWqhIg4P4KwY4dmLbuyXIx4o4YmPsvMRJYJd/w==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.3.tgz", + "integrity": "sha512-SbEG75TzH8G7eVXFSN5f9EExILKfly7SUvVY5DhhYLvfhKqhDFY0OzevWa/zwak0RLRfWS5AvfMWpd9gJvr5Yg==", "dev": true }, "slash": { @@ -5209,6 +5221,12 @@ "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", "dev": true }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "dev": true + }, "yargs": { "version": "12.0.5", "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", diff --git a/package.json b/package.json index bc0d431..67a3c22 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-mathlive", - "version": "1.3.2", - "description": "A react wrapper-component for mathlive.js", + "version": "2.0.0", + "description": "An interactive math input for react.", "main": "dist/index.js", "types": "dist/index.d.ts", "repository": { @@ -31,7 +31,7 @@ "@types/react-dom": "^16.0.11", "coveralls": "^3.0.5", "identity-obj-proxy": "^3.0.0", - "jest": "^24.8.0", + "jest": "24.7.1", "ts-jest": "^24.0.2", "typescript": "^3.2.4" }, From 4d65975cbd025b24d55a3bc2e35e88c29959e1fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Heimb=C3=BCrger?= Date: Thu, 8 Aug 2019 23:34:16 +0100 Subject: [PATCH 4/8] Update readme --- CONTRIBUTING.md | 23 +++++++++++++++++++++++ README.md | 33 +++++++++++++++++++++++++-------- 2 files changed, 48 insertions(+), 8 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..4830e5b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,23 @@ +# Contributing + +## Before contributing + +This library is a thin wrapper (the "react wrapper") around Mathlive (the "base library"). It's likely that errors encountered when using the wrapper originate in the base library. Likewise, feature-requests and feature-PRs should probably go directly into the base library as well. + +## What to contribute + +Contributions to the react-wrapper can be issues, feature-requests or pull-requests (code), that should + +* improve the interaction of react and mathlive, +* make sure best practices in react are used +* simplify using of the wrapper +* improve the general code style +* add test-cases +* adjust for new react / mathlive versions or +* fix existing bugs in the implementation. + +This wrapper does not aim to add too much functionality or additional wrapping around the base library. This minimizes the necessary maintenance to keep the wrapper compatible with future versions. + +## How to contribute + +Feel free to create an issue if you have any problem that you think originates in this wrapper. If you want to contribute code, fork the repository on github and create a pull request for master. diff --git a/README.md b/README.md index e317d34..72024e6 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,9 @@ # react-mathlive - -[![Build Status](https://semaphoreci.com/api/v1/concludio/react-mathlive/branches/master/badge.svg)](https://semaphoreci.com/concludio/react-mathlive) - +[![Build Status](https://semaphoreci.com/api/v1/concludio/react-mathlive/branches/master/shields_badge.svg)](https://semaphoreci.com/concludio/react-mathlive) [![Coverage Status](https://coveralls.io/repos/github/concludio/react-mathlive/badge.svg?branch=master)](https://coveralls.io/github/concludio/react-mathlive?branch=master) -A react-component for using [mathlive.js](https://mathlive.io)'s mathfield (interactive math editor). +A react-component using [mathlive.js](https://mathlive.io)'s mathfield (interactive math editor). ## How to install @@ -28,7 +26,7 @@ render() { return + />; } onMathChange(mathText) { @@ -38,7 +36,7 @@ onMathChange(mathText) { There is an [example](/examples/example1/) using Typescript available. -## Interacting with the native library +### Interacting with the native library The `MathfieldComponent` also allows retrieving the native [`Mathfield`-object](http://docs.mathlive.io/MathField.html) from the Mathlive-library via the `mathFieldRef`-parameter: @@ -46,8 +44,27 @@ The `MathfieldComponent` also allows retrieving the native [`Mathfield`-object]( render() { return (this.internalMathField = mf)} - /> + />; } ``` -Via the `mathFieldOptions`-parameter it's possible to provide the native `Mathfield` with [`MathFieldOptions`](http://docs.mathlive.io/tutorial-CONFIG.html). +Via the optional `mathFieldConfig`-parameter it's possible to provide the native `Mathfield` with a [`MathFieldConfig`](http://docs.mathlive.io/tutorial-CONFIG.html) on its creation: + + +```JavaScript +render() { + return ; +} +``` + +## Contribute + +This is an open source library and issues and pull requests are very welcome. + +See [Contributing](CONTRIBUTING.md). + From 10a7f62e2e9fef9751025ac489a89fa20dee22c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Heimb=C3=BCrger?= Date: Sat, 10 Aug 2019 07:51:53 +0100 Subject: [PATCH 5/8] Fix spelling --- CONTRIBUTING.md | 8 ++++---- README.md | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4830e5b..49c9fcc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,17 +2,17 @@ ## Before contributing -This library is a thin wrapper (the "react wrapper") around Mathlive (the "base library"). It's likely that errors encountered when using the wrapper originate in the base library. Likewise, feature-requests and feature-PRs should probably go directly into the base library as well. +This library is a thin wrapper (the "react wrapper") around Mathlive (the "base library"). It's likely that errors encountered when using the wrapper originate in the base library. Likewise, feature requests and feature PRs should probably go directly into the base library as well. ## What to contribute -Contributions to the react-wrapper can be issues, feature-requests or pull-requests (code), that should +Contributions to the react wrapper can be issues, feature requests or pull requests (code), that should * improve the interaction of react and mathlive, * make sure best practices in react are used -* simplify using of the wrapper +* simplify using the wrapper * improve the general code style -* add test-cases +* add test cases * adjust for new react / mathlive versions or * fix existing bugs in the implementation. diff --git a/README.md b/README.md index 72024e6..66d63b5 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Build Status](https://semaphoreci.com/api/v1/concludio/react-mathlive/branches/master/shields_badge.svg)](https://semaphoreci.com/concludio/react-mathlive) [![Coverage Status](https://coveralls.io/repos/github/concludio/react-mathlive/badge.svg?branch=master)](https://coveralls.io/github/concludio/react-mathlive?branch=master) -A react-component using [mathlive.js](https://mathlive.io)'s mathfield (interactive math editor). +A react component using [mathlive.js](https://mathlive.io)'s mathfield (interactive math editor). ## How to install @@ -13,13 +13,13 @@ You can install *react-mathlive* like any other Javascript or Typescript library npm i react-mathlive ``` -For Typescript users: As *react-mathlive* is written in Typescript, it comes with it's own typings. +For Typescript users: As *react-mathlive* is written in Typescript, it comes with its own typings. ## How to use -This text assumes you know [how to build simple react-components](https://reactjs.org/tutorial/tutorial.html). +This text assumes you know [how to build simple react components](https://reactjs.org/tutorial/tutorial.html). -You can use the `MathfieldComponent` in your web-application as follows: +You can use the `MathFieldComponent` in your web application as follows: ```JSX render() { @@ -34,11 +34,11 @@ onMathChange(mathText) { } ``` -There is an [example](/examples/example1/) using Typescript available. +There is also an [example Typescript react application](/examples/example1/) using this library. ### Interacting with the native library -The `MathfieldComponent` also allows retrieving the native [`Mathfield`-object](http://docs.mathlive.io/MathField.html) from the Mathlive-library via the `mathFieldRef`-parameter: +The `MathFieldComponent` also allows retrieving the native [`MathField` object](http://docs.mathlive.io/MathField.html) from the Mathlive library via the `mathFieldRef` parameter: ```JavaScript render() { @@ -48,10 +48,10 @@ render() { } ``` -Via the optional `mathFieldConfig`-parameter it's possible to provide the native `Mathfield` with a [`MathFieldConfig`](http://docs.mathlive.io/tutorial-CONFIG.html) on its creation: +Via the optional `mathFieldConfig` parameter it is possible to provide the native `MathField` with a [`MathFieldConfig`](http://docs.mathlive.io/tutorial-CONFIG.html) on its creation: -```JavaScript +```JSX render() { return Date: Mon, 14 Oct 2019 15:06:42 +0200 Subject: [PATCH 6/8] Allow controlled and uncontrolled usage --- examples/example1/package-lock.json | 2 +- package-lock.json | 6 ++--- package.json | 2 +- src/MathFieldComponent.test.tsx | 13 ++++------ src/MathFieldComponent.tsx | 38 ++++++++++++++++++++++------- 5 files changed, 38 insertions(+), 23 deletions(-) diff --git a/examples/example1/package-lock.json b/examples/example1/package-lock.json index 6cbd823..4e30d59 100644 --- a/examples/example1/package-lock.json +++ b/examples/example1/package-lock.json @@ -10118,7 +10118,7 @@ "react-mathlive": { "version": "file:../..", "requires": { - "mathlive": ">= 0.32.1 < 1", + "mathlive": "file:../../../mathlive", "react": "^16.7.0", "react-dom": "^16.7.0" } diff --git a/package-lock.json b/package-lock.json index 361c120..02c3e55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "react-mathlive", - "version": "1.3.2", + "version": "2.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -3467,9 +3467,7 @@ } }, "mathlive": { - "version": "0.32.1", - "resolved": "https://registry.npmjs.org/mathlive/-/mathlive-0.32.1.tgz", - "integrity": "sha512-iKVTL89SCgKsqd1oaIr/is1HVlEE2myGSVTv7g9pTcxGt8QaSb2z17HmLqfPYBvNNCUGzDvoJyXz8adXoJEadQ==" + "version": "file:../mathlive" }, "mem": { "version": "4.3.0", diff --git a/package.json b/package.json index 67a3c22..07f3834 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "typescript": "^3.2.4" }, "dependencies": { - "mathlive": ">= 0.32.1 < 1", + "mathlive": "file:../mathlive", "react": "^16.7.0", "react-dom": "^16.7.0" } diff --git a/src/MathFieldComponent.test.tsx b/src/MathFieldComponent.test.tsx index cc00019..23fb685 100644 --- a/src/MathFieldComponent.test.tsx +++ b/src/MathFieldComponent.test.tsx @@ -23,9 +23,11 @@ describe("combineConfig", () => { }, }); - combinedConfig.onContentDidChange!({ + const mockMathField = { $latex: () => "bar", - }); + } as MathField; + + combinedConfig.onContentDidChange!(mockMathField); expect(value1).toBe("bar"); expect(value2).toBe("bar"); @@ -81,6 +83,7 @@ describe("MathFieldComponent", () => { return this.mathField = mf} latex={this.state.value} + />; } } @@ -98,12 +101,6 @@ describe("MathFieldComponent", () => { test("invalidly created instances throw correct errors", () => { const mathFieldComponent = new MathFieldComponent({ latex: "fubar" }); - try { - mathFieldComponent.componentWillReceiveProps({ latex: "baz" }); - fail("The previous line should have thrown."); - } catch (e) { - expect(e.message).toBe("Component was not correctly initialized."); - } try { mathFieldComponent.componentDidMount(); diff --git a/src/MathFieldComponent.tsx b/src/MathFieldComponent.tsx index f246ca2..024cfdd 100644 --- a/src/MathFieldComponent.tsx +++ b/src/MathFieldComponent.tsx @@ -3,8 +3,7 @@ import 'mathlive/dist/mathlive.css'; import * as React from 'react'; import { makeMathField } from 'mathlive'; -export interface Props { - latex: string; +interface BaseProps { onChange?: (latex: string) => void; /** @@ -18,6 +17,18 @@ export interface Props { mathFieldRef?: (mathfield: MathField) => void; } +interface ControlledProps extends BaseProps { + latex: string; + initialLatex?: undefined; +} + +interface UncontrolledProps extends BaseProps { + latex?: undefined; + initialLatex: string; +} + +export type Props = ControlledProps | UncontrolledProps; + export function combineConfig(props: Props): MathFieldConfig { const combinedConfiguration: MathFieldConfig = { ...props.mathFieldConfig @@ -46,19 +57,21 @@ export class MathFieldComponent extends React.Component { private readonly combinedConfiguration = combineConfig(this.props); private mathField: MathField | undefined; - componentWillReceiveProps(newProps: Props) { + componentDidUpdate(prevProps: Props) { if (!this.mathField) { throw new Error("Component was not correctly initialized."); } - if (newProps.latex !== this.props.latex) { - this.mathField.$latex(newProps.latex, { suppressChangeNotifications: true }); + if (prevProps.latex !== undefined) { + if (this.props.latex === undefined) { + throw new Error("Cannot change from controlled to uncontrolled state!"); + } + if (this.props.latex !== prevProps.latex) { + this.mathField.$latex(this.props.latex, { suppressChangeNotifications: true }); + } } } - /** The domain of react ends here, so it should not render again. */ - shouldComponentUpdate() { return false; } - render() { return
this.insertElement = instance} />; } @@ -67,9 +80,16 @@ export class MathFieldComponent extends React.Component { if (!this.insertElement) { throw new Error("React did apparently not mount the insert point correctly."); } + + let initialValue: string; + if (this.props.initialLatex !== undefined) { + initialValue = this.props.initialLatex; + } else { + initialValue = this.props.latex; + } this.mathField = makeMathField(this.insertElement, this.combinedConfiguration); - this.mathField.$latex(this.props.latex, { suppressChangeNotifications: true }); + this.mathField.$latex(initialValue, { suppressChangeNotifications: true }); if (this.props.mathFieldRef) { this.props.mathFieldRef(this.mathField); From e16649751c8be3bfac9f1a358d630618e5d12808 Mon Sep 17 00:00:00 2001 From: Fabian Grewing Date: Wed, 30 Oct 2019 16:20:01 +0100 Subject: [PATCH 7/8] Use latest mathlive version --- package-lock.json | 4 +++- package.json | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 02c3e55..56a70bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3467,7 +3467,9 @@ } }, "mathlive": { - "version": "file:../mathlive" + "version": "0.32.3", + "resolved": "https://registry.npmjs.org/mathlive/-/mathlive-0.32.3.tgz", + "integrity": "sha512-6IYFuNkU4gRX0+ILE+iI/jvi+PNoewPjfmcCjM1+VQ/mvFN7VXrQpsVJYEnP4aq47wa/nDSgLR0FZ18nU3dC0g==" }, "mem": { "version": "4.3.0", diff --git a/package.json b/package.json index 07f3834..d24075a 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "typescript": "^3.2.4" }, "dependencies": { - "mathlive": "file:../mathlive", + "mathlive": ">= 0.32.3 < 1", "react": "^16.7.0", "react-dom": "^16.7.0" } From 457c60907ff9576b22ec2e6b68ac64547f6454d4 Mon Sep 17 00:00:00 2001 From: Fabian Grewing Date: Wed, 30 Oct 2019 16:37:11 +0100 Subject: [PATCH 8/8] Update example --- examples/example1/package-lock.json | 72 +---------------------------- examples/example1/src/App.tsx | 27 +++++------ 2 files changed, 13 insertions(+), 86 deletions(-) diff --git a/examples/example1/package-lock.json b/examples/example1/package-lock.json index a1ee882..1799d36 100644 --- a/examples/example1/package-lock.json +++ b/examples/example1/package-lock.json @@ -10118,79 +10118,9 @@ "react-mathlive": { "version": "file:../..", "requires": { - "mathlive": "file:../../../mathlive", + "mathlive": ">= 0.32.3 < 1", "react": "^16.7.0", "react-dom": "^16.7.0" - }, - "dependencies": { - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "mathlive": { - "version": "0.32.1", - "resolved": "https://registry.npmjs.org/mathlive/-/mathlive-0.32.1.tgz", - "integrity": "sha512-iKVTL89SCgKsqd1oaIr/is1HVlEE2myGSVTv7g9pTcxGt8QaSb2z17HmLqfPYBvNNCUGzDvoJyXz8adXoJEadQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "react": { - "version": "16.9.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.9.0.tgz", - "integrity": "sha512-+7LQnFBwkiw+BobzOF6N//BdoNw0ouwmSJTEm9cglOOmsg/TMiFHZLe2sEoN5M7LgJTj9oHH0gxklfnQe66S1w==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2" - } - }, - "react-dom": { - "version": "16.9.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.9.0.tgz", - "integrity": "sha512-YFT2rxO9hM70ewk9jq0y6sQk8cL02xm4+IzYBz75CQGlClQQ1Bxq0nhHF6OtSbit+AIahujJgb/CPRibFkMNJQ==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.15.0" - } - }, - "react-is": { - "version": "16.9.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz", - "integrity": "sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw==" - }, - "scheduler": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.15.0.tgz", - "integrity": "sha512-xAefmSfN6jqAa7Kuq7LIJY0bwAPG3xlCj0HMEBQk1lxYiDKZscY2xJ5U/61ZTrYbmNQbXa+gc7czPkVo11tnCg==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - } } }, "react-scripts": { diff --git a/examples/example1/src/App.tsx b/examples/example1/src/App.tsx index 476b024..d6d661b 100644 --- a/examples/example1/src/App.tsx +++ b/examples/example1/src/App.tsx @@ -11,21 +11,18 @@ class App extends React.Component<{}, State> { public render() { return (
-

- MathField: - -

-

- TextField: - this.onLatexChange(ev.target.value)} - /> -

+ MathField: + +
+ TextField: + this.onLatexChange(ev.target.value)} + />
); }