GithubHelp home page GithubHelp logo

rip21 / react-simplemde-editor Goto Github PK

View Code? Open in Web Editor NEW
753.0 8.0 103.0 6.92 MB

React wrapper for simplemde (easymde) markdown editor

Home Page: https://react-simplemde-edtior.netlify.com/

License: MIT License

TypeScript 79.55% HTML 8.40% JavaScript 12.05%
simplemde react markdown editor easymde marked marked-js

react-simplemde-editor's Introduction

React SimpleMDE (EasyMDE) Markdown Editor

NPM version

React component wrapper for EasyMDE (the most fresh SimpleMDE fork).

Only two dependencies, React (peer) and EasyMDE (peer).

Built by @RIP21 ๐Ÿ‘จโ€๐Ÿ’ป

Table of contents generated with markdown-toc

New in v5

  • [breaking] Full rewrite to hooks. Means more reactive so, probably, less bugs related with updates. Minimum React version required >=16.8.2
  • [breaking] easymde now a peer dependency, please install it manually
  • [breaking] label prop has been removed
  • [breaking] SSR safe nets removed, please make sure to import it dynamically
  • [breaking] options shall be memoized to prevent new instances from being created on each render and other related to that bugs (more on that below)
  • [potentially-breaking] Forwards ref, so you can easily get access to div wrapper by using ref prop.
  • [potentially-breaking] Lots of bugs fixed, examples updated
  • [potentially-breaking] @babel/runtime helpers are no longer inlined but imported.

Install

npm install --save react-simplemde-editor easymde

Note: Possibly you may need to install @babel/runtime, try without it, but if you don't have any issues, then you shouldn't.

Demo

Hosted demo

or to see it locally:

git clone https://github.com/RIP21/react-simplemde-editor.git
cd react-simplemde-editor
yarn install
yarn demo
open browser at localhost:3000

Usage

View the demo code for more examples.

All examples below are in TypeScript

Uncontrolled usage

import React from "react";
import SimpleMDE from "react-simplemde-editor";
import "easymde/dist/easymde.min.css";

<SimpleMDE />;

Controlled usage

export const ControlledUsage = () => {
  const [value, setValue] = useState("Initial value");

  const onChange = useCallback((value: string) => {
    setValue(value);
  }, []);

  return <SimpleMdeReact value={value} onChange={onChange} />;
};

Options

You can set API of SimpleMDE options which you pass down as a options prop. If you're using TypeScript it will be inferred by compiler.

Note: if you don't specify a custom id it will automatically generate an id for you.

Note that you need to useMemo to memoize options so they do not change on each rerender! It will affect behavior and performance because then on each render of the parent that renders SimpleMdeReact you'll get a new instance of the editor, which you definitely want to avoid! Also, if you change options on each value change you will lose focus. So, put options as a const outside of the component, or if options shall be partially or fully set by props make sure to useMemo in case of functional/hooks components, or class field for class based components. Slightly more on that here: #164

export const UsingOptions = () => {
  const [value, setValue] = useState("Initial");

  const onChange = useCallback((value: string) => {
    setValue(value);
  }, []);

  const autofocusNoSpellcheckerOptions = useMemo(() => {
    return {
      autofocus: true,
      spellChecker: false,
    } as SimpleMDE.Options;
  }, []);

  return (
    <SimpleMdeReact
      options={autofocusNoSpellcheckerOptions}
      value={value}
      onChange={onChange}
    />
  );
};

Hotkeys

You can include key maps using the extraKeys prop. Read more at CodeMirror extra keys

export const UpdateableByHotKeys = () => {
  const extraKeys = useMemo<KeyMap>(() => {
    return {
      Up: function (cm) {
        cm.replaceSelection(" surprise. ");
      },
      Down: function (cm) {
        cm.replaceSelection(" surprise again! ");
      },
    };
  }, []);

  const [value, setValue] = useState("initial");
  const onChange = (value: string) => setValue(value);

  return (
    <SimpleMdeReact value={value} onChange={onChange} extraKeys={extraKeys} />
  );
};

Custom preview rendering example

import ReactDOMServer from "react-dom/server";

export const CustomPreview = () => {
  const customRendererOptions = useMemo(() => {
    return {
      previewRender() {
        return ReactDOMServer.renderToString(
          <ReactMarkdown
            source={text}
            renderers={{
              CodeBlock: CodeRenderer,
              Code: CodeRenderer,
            }}
          />
        );
      },
    } as SimpleMDE.Options;
  }, []);

  return (
    <div>
      <h4>Custom preview</h4>
      <SimpleMdeReact options={customRendererOptions} />
    </div>
  );
};

Events / Additional event listeners for events of CodeMirror

See full list of events here

import { SimpleMdeReact } from "react-simplemde-editor";
import type { SimpleMdeToCodemirrorEvents } from "react-simplemde-editor";

export const CustomEventListeners = () => {
  const [value, setValue] = useState("Initial value");

  const onChange = useCallback((value: string) => {
    setValue(value);
  }, []);

  // Make sure to always `useMemo` all the `options` and `events` props to ensure best performance!
  const events = useMemo(() => {
    return {
      focus: () => console.log(value),
    } as SimpleMdeToCodemirrorEvents;
  }, []);

  return <SimpleMdeReact events={events} value={value} onChange={onChange} />;
};

Autosaving

export const Autosaving = () => {
  const delay = 1000;
  const autosavedValue = localStorage.getItem(`smde_demo`) || "Initial value";
  const anOptions = useMemo(() => {
    return {
      autosave: {
        enabled: true,
        uniqueId: "demo",
        delay,
      },
    };
  }, [delay]);

  return (
    <SimpleMdeReact id="demo" value={autosavedValue} options={anOptions} />
  );
};

Retrieve easymde, codemirror or cursor info to be able to manipulate it.

export const GetDifferentInstances = () => {
  // simple mde
  const [simpleMdeInstance, setMdeInstance] = useState<SimpleMDE | null>(null);

  const getMdeInstanceCallback = useCallback((simpleMde: SimpleMDE) => {
    setMdeInstance(simpleMde);
  }, []);

  useEffect(() => {
    simpleMdeInstance &&
      console.info("Hey I'm editor instance!", simpleMdeInstance);
  }, [simpleMdeInstance]);

  // codemirror
  const [codemirrorInstance, setCodemirrorInstance] = useState<Editor | null>(
    null
  );
  const getCmInstanceCallback = useCallback((editor: Editor) => {
    setCodemirrorInstance(editor);
  }, []);

  useEffect(() => {
    codemirrorInstance &&
      console.info("Hey I'm codemirror instance!", codemirrorInstance);
  }, [codemirrorInstance]);

  // line and cursor
  const [lineAndCursor, setLineAndCursor] = useState<Position | null>(null);

  const getLineAndCursorCallback = useCallback((position: Position) => {
    setLineAndCursor(position);
  }, []);

  useEffect(() => {
    lineAndCursor &&
      console.info("Hey I'm line and cursor info!", lineAndCursor);
  }, [lineAndCursor]);

  return (
    <div>
      <h4>Getting instance of Mde and codemirror and line and cursor info</h4>
      <SimpleMdeReact
        value="Go to console to see stuff logged"
        getMdeInstance={getMdeInstanceCallback}
        getCodemirrorInstance={getCmInstanceCallback}
        getLineAndCursor={getLineAndCursorCallback}
      />
    </div>
  );
};

Basic testing

Here is how you do it. It requires mock of certain browser pieces to work, but this is whole example.

import { act, render, screen } from "@testing-library/react";
import { useState } from "react";
import { SimpleMdeReact } from "react-simplemde-editor";
import userEvent from "@testing-library/user-event";

// @ts-ignore
Document.prototype.createRange = function () {
  return {
    setEnd: function () {},
    setStart: function () {},
    getBoundingClientRect: function () {
      return { right: 0 };
    },
    getClientRects: function () {
      return {
        length: 0,
        left: 0,
        right: 0,
      };
    },
  };
};

const Editor = () => {
  const [value, setValue] = useState("");
  return <SimpleMdeReact value={value} onChange={setValue} />;
};

describe("Renders", () => {
  it("succesfully", async () => {
    act(() => {
      render(<Editor />);
    });
    const editor = await screen.findByRole("textbox");
    userEvent.type(editor, "hello");
    expect(screen.getByText("hello")).toBeDefined();
  });
});

API

Props

export interface SimpleMDEReactProps
  extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange"> {
  id?: string;
  onChange?: (value: string, changeObject?: EditorChange) => void;
  value?: string;
  extraKeys?: KeyMap;
  options?: SimpleMDE.Options;
  events?: SimpleMdeToCodemirrorEvents;
  getMdeInstance?: GetMdeInstance;
  getCodemirrorInstance?: GetCodemirrorInstance;
  getLineAndCursor?: GetLineAndCursor;
  placeholder?: string;
  textareaProps?: Omit<
    React.HTMLAttributes<HTMLTextAreaElement>,
    "id" | "style" | "placeholder"
  >;
}

All exports list

default - SimpleMdeReact

SimpleMdeReact - same as default but named

Types:

SimpleMdeReactProps - props of the component

DOMEvent - certain events that are used to get events exported below

CopyEvents - only copy codemirror events

GlobalEvents - some other global codemirror events

DefaultEvent - default codemirror event handler function

IndexEventsSignature - index signature that expects string as key and returns DefaultEvent

SimpleMdeToCodemirrorEvents - manually crafted events (based off @types/[email protected] that easymde uses internally) + all the above merged together into whole mapping between Codemirror event names and actual handlers for events prop

GetMdeInstance - signature of the callback function that retrieves mde instance

GetCodemirrorInstance - signature of the callback function that retrieves codemirror instance

GetLineAndCursor - signature of the callback function that retrieves line and cursor info

Changelog

New in v4

  • Now uses EasyMDE (the most fresh SimpleMDE fork) instead of simplemde itself. Possible breaking changes, so I bumped version to v4.
  • One obvious breaking change. Is how CSS is have to be imported. It used to be simplemde/dist/simplemde.min.css now it will be easymde/dist/easymde.min.css

New in v3

  • The initialValue prop has been removed and replaced with a value prop, allowing direct changes to the value to be made after the component mounts.
  • v3.6.8 if rendering server-side, you can set static ids to avoid errors in rendering synchronization.
  • v3.6.17 TypeScript typings added.
  • v3.6.19 All props will be passed to the wrapper now (except a id, onChange and few others that are ignored)
  • v3.6.21 React 17 support (UNSAFE methods are no longer used)

New in v2

Version 1.0 did not have SimpleMDE options configured well, this readme reflects the changes made to better include options. This is still a very new project. Testing, feedback and PRs are welcome and appreciated.

react-simplemde-editor's People

Contributors

benjamindehli avatar benmliang avatar benrlodge avatar btzr-io avatar captainsafia avatar ccostel avatar chesterzengjian avatar ctc-phil avatar dependabot[bot] avatar gabpaet avatar gjvpaet avatar jaeseokim avatar johennes avatar linusu avatar live-small avatar pridgey avatar rip21 avatar rkrx avatar sperezp avatar stefkors avatar thgreasi avatar toneplex avatar tonyjmnz avatar tylercaldwell avatar xwchris avatar y-yagi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-simplemde-editor's Issues

Export SimpleMDEEditorProps

Can you export your type SimpleMDEEditorProps ? It would be really useful for me since I want to use styled-components on it and still have props completion afterwards.

Latest version 3.6.6 don't have changes included in source files bundled in dist

Imports by default is importing react-simplemde-editor.js which is in the dist folder. And that one don't have changes that have been added into the source code in version 3.6.5. (solving navigator and id problems for server-side rendering)

Please rebuild and deploy it again making sure that changes are appear in react-simplemde-editor.js file in dist folder.
Maybe it was my mistake, that I didn't commit dist with new changes to not spam into diffs. But you didn't notice that in pull request and released it as is :)
Sorry :)
And please add to the readme.md info that you can set static id for this component to avoid errors in server-side rendering synchronization so people now that this is available and do not open an issue for that.

Thanks.

Workaround for this issue is just explicitly import react-simplemde-editor/src/index.js

Textarea spans page width. Inline styles not working

I am trying to increase the margin around the editor but nothing seems to be working. New to React and this is my first solo project.

My Text.js file looks something like this:

import SimpleMDEReact from 'react-simplemde-editor';
import 'simplemde/dist/simplemde.min.css';

// some logic

const editorStyle = {
  margin: '2em 2em'
};

// more logic

// editor

<button
  style={{ display: "inline-block", margin: "10px 0" }}
    onClick={this.handleTextChange}>
     Click me to update the textValue outside of the editor
</button>
 <SimpleMDEReact
    editorStyle={editorStyle}
     label="Markdown Editor"
     value={this.state.textValue1}
     onChange={this.handleChange1}
     options={{
         autofocus: true,
         spellChecker: true,
     }}
 />

Not sure how to increase the margins here.

Mounting component in Enzyme throws error

console.log node_modules/easymde/src/js/easymde.js:1386 EasyMDE: Error. No element was found. console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
This is what I get when I try to mount the component with SimpleMDE editor.

It works only with shallow but then I can't access nested elements. Anyone knows a solution for this?

Add support for or docs for autosaving capabilities

Hi! I'm trying to enable autosave, but it doesn't work. As the form loads, I am setting it's value from the state, so it seems to clear all the text simplemde has saved.

Is there a workaround for this?

Does react-simplemde-editor clean up after itself?

Hi, I'm considering using simplemde for a React app I'm working on. This library you've created would make that super simple! One question I have, though, is if react-simplemde-editor cleans up after itself. According to this issue: https://github.com/NextStepWebs/simplemde-markdown-editor/issues/142, there are problems with using simplemde because it leaves instances hanging around. I took a look at your source code, and at first glance, it doesn't appear to handle this automatically. Maybe I'm wrong, however.

textarea element needs title attribute or label for accessibility

According to WCAG 2.0, textarea form controls (and just about every other interactive UI element) should have a name, role and value. The textarea generated by React.createElement in your code does not give it a name.

Their techniques page indicates that the name comes from

<label> element associated with it or title attribute

See also their examples for basic HTML techniques.

Can I suggest you pass through a title prop to the textarea? Probably easier than adding a label and having to style that.

PS. I discovered this using the handy HTML_CodeSniffer tool.

setting ininital value with passing "value" to the options doesn't work

passing "value" as an option doesn't set the initial state during first render, it showed the editor empty, passing it as initialValue though in options just like the Simple mde configuration options worked for me.

just wanted to share it in case somebody had trouble with this.

All in all great package thanks a lot.

Problem with SSR in Next.js

When using this component together with Next.js, I'm running into trouble when the component is first rendered on the server.

Cannot read property 'getElementsByClassName' of null

Currently I'm working around this by hiding the component, and only showing it after componentDidMount, but this is a bit annoying to have to do this every time.

I'm guessing that the problem has something to do with it trying to load SimpleMDE even on the server. It would be nice if maybe we could detect this (e.g. typeof window) and simply defer until componentDidMount have triggered.

The change in value prop does not change the text displayed in editor

I am probably missing something simple but I have a question regarding the value prop.

Below is the code that illustrates my problem.

import * as React from 'react';
import * as SimpleMDEReact from 'react-simplemde-editor';
import 'react-simplemde-editor/demo/dist/stylesheets/vendor.css';

export default class Note extends React.Component {
  public state = { value: '' };

  public handleEditorChange = (value: string) => {
    this.setState({ value: "asdfsdf" });
  };

  public render() {
    return (
      <SimpleMDEReact
        onChange={this.handleEditorChange}
        options={{ autofocus: true, spellChecker: true }}
        value={this.state.value}
      />
    );
  }
}

The handleEditorChange is called whenever user types anything.
In this method, I am currently setting value to something gibberish.
I am passing this value to the SimpleMDEReact component.

Expectation-
The SimpleMDEReact component should show only the value prop passed.

Observation-
The SimpleMDEReact component does not show what is passed in the value prop. Instead, it shows what the user types.

Support image upload?

Is it possible to provide a button or a drag-and-drop area and the corresponding APIs for users to upload images?

Call for contibutors

Hi everyone.
I took over this project from the @benrlodge to support this one more actively.

I collect here all of the most updated forks to unite all your work in one place so all of us could benefit.

So, please.
@jwelfare
@taleship
@appsumo
@janprasil
@interviewstreet

You have few commits ahead please feel free to create PR with some explanation of what you did. I will be happy to merge them ASAP and deploy new version afterward when I will be added as a collab in NPM.

Thanks, and let's make it better :)

React 16, better build etc is all planned. But if you have it already, I will be happy to save my time.
Thanks!

anchor tags have no link content or id, buttons would be better

For accessibility reasons, anchor tags should have valid link content/text or at the very least, an id attribute.

I think an id would maybe be the easiest to add, maybe with the prefix from the instance of the editor itself so you can ensure a unique value if multiple editors are on a page.

Ideally, you would replace them all with button elements, which would probably be more semantically correct. See the recommendation regarding accessibility in the MDN docs

Problems with server-side rendering. Navigator is not defined

This component is actually cannot work with server-side rendering applications. And throws error looks like
ReferenceError: navigator is not defined
It's a problem with codemirror component which is dependency of original simplemde project.
I already have a proven workaround which is used in react-codemirror project.
PR request will be in a few minutes.

Unable to render component from jest

I have a simple typescript react application using webpack, created with create-react-app. SimpleMDEEditor works fine in the browser, but if I render it in a jest test, it throws the following exception:

TypeError: Cannot read property 'getElementsByClassName' of null at SimpleMDEEditor._this.addEvents (node_modules/react-simplemde-editor/lib/index.js:97:34) at SimpleMDEEditor.componentDidMount (node_modules/react-simplemde-editor/lib/index.js:147:14) at commitLifeCycles (node_modules/react-dom/cjs/react-dom.development.js:14685:22) at commitAllLifeCycles (node_modules/react-dom/cjs/react-dom.development.js:15905:7) at HTMLUnknownElement.callCallback (node_modules/react-dom/cjs/react-dom.development.js:145:14) at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:193:27) at HTMLUnknownElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9) at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17) at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27) at HTMLUnknownElement.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21) at Object.invokeGuardedCallbackDev (node_modules/react-dom/cjs/react-dom.development.js:195:16) at invokeGuardedCallback (node_modules/react-dom/cjs/react-dom.development.js:248:31) at commitRoot (node_modules/react-dom/cjs/react-dom.development.js:16075:7) at completeRoot (node_modules/react-dom/cjs/react-dom.development.js:17463:3) at performWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:17391:9) at performWork (node_modules/react-dom/cjs/react-dom.development.js:17295:7) at performSyncWork (node_modules/react-dom/cjs/react-dom.development.js:17267:3) at requestWork (node_modules/react-dom/cjs/react-dom.development.js:17155:5) at scheduleWork (node_modules/react-dom/cjs/react-dom.development.js:16949:5) at scheduleRootUpdate (node_modules/react-dom/cjs/react-dom.development.js:17637:3) at updateContainerAtExpirationTime (node_modules/react-dom/cjs/react-dom.development.js:17664:10) at updateContainer (node_modules/react-dom/cjs/react-dom.development.js:17691:10) at ReactRoot.Object.<anonymous>.ReactRoot.render (node_modules/react-dom/cjs/react-dom.development.js:17957:3) at node_modules/react-dom/cjs/react-dom.development.js:18097:14 at unbatchedUpdates (node_modules/react-dom/cjs/react-dom.development.js:17518:10) at legacyRenderSubtreeIntoContainer (node_modules/react-dom/cjs/react-dom.development.js:18093:5) at Object.render (node_modules/react-dom/cjs/react-dom.development.js:18152:12) at Object.<anonymous> (src/MyComponent.test.tsx:32:18)

Get current location of cursor

I'm wondering if there is a way to get the current position of the cursor? And if I can use codemirror functions like getCursor()?

Problems with the rendering SimpleMDE component

Hi there.
I have an issue with the rendering. And it cause by wrong building of your module or something like that.
Once I'm import or require your component this way:
import SimpleMDE from 'react-simplemde-editor';
And then add it to the render method, the following problem appear.
Uncaught Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. Check the render method of EditPostForm.

Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components). Check the render method of EditPostForm.

It figured later that It can be fixed importing module this way
import SimpleMDE from 'react-simplemde-editor/src';
It start to work fine, but also start to log tons of shit to the webpack console looks like that (last 20 rows of that)


  [920] ./~/react-simplemde-editor/~/react/lib/ReactDefaultPerfAnalysis.js 5.79 kB {0} [built]
  [921] ./~/react-simplemde-editor/~/fbjs/lib/performanceNow.js 844 bytes {0} [built]
  [922] ./~/react-simplemde-editor/~/fbjs/lib/performance.js 612 bytes {0} [built]
  [923] ./~/react-simplemde-editor/~/react/lib/ReactVersion.js 379 bytes {0} [built]
  [924] ./~/react-simplemde-editor/~/react/lib/renderSubtreeIntoContainer.js 463 bytes {0} [built]
  [925] ./~/react-simplemde-editor/~/react/lib/ReactDOMServer.js 766 bytes {0} [built]
  [926] ./~/react-simplemde-editor/~/react/lib/ReactServerRendering.js 3.3 kB {0} [built]
  [927] ./~/react-simplemde-editor/~/react/lib/ReactServerBatchingStrategy.js 673 bytes {0} [built]
  [928] ./~/react-simplemde-editor/~/react/lib/ReactServerRenderingTransaction.js 2.3 kB {0} [built]
  [929] ./~/react-simplemde-editor/~/react/lib/ReactIsomorphic.js 2.05 kB {0} [built]
  [930] ./~/react-simplemde-editor/~/react/lib/ReactDOMFactories.js 3.36 kB {0} [built]
  [931] ./~/react-simplemde-editor/~/react/lib/ReactElementValidator.js 10.8 kB {0} [built]
  [932] ./~/react-simplemde-editor/~/fbjs/lib/mapObject.js 1.47 kB {0} [built]
  [933] ./~/react-simplemde-editor/~/react/lib/onlyChild.js 1.21 kB {0} [built]
  [934] ./~/react-simplemde-editor/~/react/lib/deprecated.js 1.77 kB {0} [built]
  [935] ./~/simplemde/dist/simplemde.min.js 269 kB {0} [built]
  [936] ./~/react-simplemde-editor/src/services/idGenerator.js 98 bytes {0} [built]
  [937] ./~/react-simplemde-editor/src/utils/noop.js 32 bytes {0} [built]

WARNING in ./~/simplemde/dist/simplemde.min.js
Critical dependencies:
7:417-424 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.
 @ ./~/simplemde/dist/simplemde.min.js 7:417-424

For me (I'm very new in JS and webpack etc.) It looks like a problem with building process of the package. Guys from one of the local JS chats who helped me figure that out saying that you include to the build all React itself or something like that.
Anyway, I like your component very much, but please fix it :)
My particular use case you can find out at this repo.
https://github.com/RIP21/ololos-blog
components/post/EditPostForm.js

Error fs

I got this in the console when I install your packages and import the module

Error in ./~/typo-js/typo.js Module not found: Error: Cannot resolve module 'fs'

Error if add component without toolbar

react-simplemde-editor.js:144 
Uncaught TypeError: Cannot read property 'addEventListener' of undefined
    at Constructor.addEvents (react-simplemde-editor.js:144)
    at Constructor.componentDidMount (react-simplemde-editor.js:90)
    at ReactCompositeComponent.js:265
    at measureLifeCyclePerf (ReactCompositeComponent.js:75)
    at ReactCompositeComponent.js:264
    at CallbackQueue.notifyAll (CallbackQueue.js:76)
    at ReactReconcileTransaction.close (ReactReconcileTransaction.js:80)
    at ReactReconcileTransaction.closeAll (Transaction.js:206)
    at ReactReconcileTransaction.perform (Transaction.js:153)
    at batchedMountComponentIntoNode (ReactMount.js:126)

Here is the error appear if you don't have any toolbar on the element. It just can't add event listener to undefined toolbar elements if I understand it correct.

The main problem with that that all next editors added to the page are unable to be rendered after this error.
I have no time to fix it right now cause now very familiar with all this eventListeners in JavaScript (I'm Java guy, sorry, and have no knowledge of lots of core of JS)

A temporary and ugly workaround is to use option named hideIcons passing there all icons that toolbar has. It will left out ugly line on the top of textbox. You can then style it as display: none (I assume that you can hide it even without hideIcons option this way)

Hope you will have some :) Otherwise, someday I will find some time and fix it :)

Switch to upstream fork?

It seems like development has stalled on SimpleMDE, and the developers seem unresponsive. There is a number of PRs open that haven't been merged, and no commits have been made the past few years ๐Ÿ˜ž

This fork seems to be the most active one and includes some nice fixes that I would love to get in:

https://github.com/Ionaru/easy-markdown-editor

What do you think about switching to that fork?

Any way to control value directly

Instead of using initialValue...

Something like:

<ReactSimpleMDE
    value: this.props.value
/>

So that it can be controlled by some higher level component?

The value of the editor is not updated

I have an issue in my app where I'm using the editor.

I use the editor in a CMS like applications. There is no issue in the first use of the editor in the app, the init value is correct. But when I change the current "edited page", the field still displayed the old value (previous edited page). I still can edit the editor, and it's ok, but the "init value" is wrong.

The value is correctly set as you can see in the screenshot but the value displayed is wrong. I tried many things but I failed to solve this.

Could you help me on that?

Here is a screenshot (as you can see the input above the editor works properly, it's not a react issue)

Here is the code:

          <SimpleMDE
            onChange={this.props.setArticleDescription}
            value={content.description}
            options={{
              autoDownloadFontAwesome: false,
              hideIcons: [
              ...
              ],
              spellChecker: false,
              status: false
            }}
          />

import 'easymde/dist/easymde.min.css' accour window is not defined in ssr

I use react ssr to introduce the css file into the component, and I get an error, window is not defined
i install react-simplemde-editor and easymde in my project, the webpack loader as follows, can you help me to solve this problem, thank you

{
        test: /\.jsx?$/,
        exclude: [
          node_modules
        ],
        loader: 'babel-loader',
      },
      {
        test: /\.(png|jpg|gif|svg)$/,
        loader: 'file-loader',
        options: {
          name: '[name].[ext]?[hash]'
        }
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
 }

How to get access to the HTML string ?

I am trying to store the HTML string and will be using it later for a different application, so I wanted to know how can I access the HTML string that might be generated while showing it in preview.

Thanks

babel-runtime

I've installed the package via NPM, but there seems to be a few missing dependencies - Unsure if I've missed a step somewhere...

Any help much appreciated!

ERROR in ./node_modules/react-simplemde-editor/lib/index.js
Module not found: Error: Can't resolve 'babel-runtime/core-js/object/assign' in '/home/nathan/code/bath-north-labour/node_modules/react-simplemde-editor/lib'
 @ ./node_modules/react-simplemde-editor/lib/index.js 13:14-60
 @ ./distribution/app/components/views/page.js
 @ ./distribution/app/components/app.js
 @ ./distribution/app/client.js

ERROR in ./node_modules/react-simplemde-editor/lib/index.js
Module not found: Error: Can't resolve 'babel-runtime/core-js/object/entries' in '/home/nathan/code/bath-north-labour/node_modules/react-simplemde-editor/lib'
 @ ./node_modules/react-simplemde-editor/lib/index.js 9:15-62
 @ ./distribution/app/components/views/page.js
 @ ./distribution/app/components/app.js
 @ ./distribution/app/client.js

ERROR in ./node_modules/react-simplemde-editor/lib/index.js
Module not found: Error: Can't resolve 'babel-runtime/helpers/classCallCheck' in '/home/nathan/code/bath-north-labour/node_modules/react-simplemde-editor/lib'
 @ ./node_modules/react-simplemde-editor/lib/index.js 17:23-70
 @ ./distribution/app/components/views/page.js
 @ ./distribution/app/components/app.js
 @ ./distribution/app/client.js

ERROR in ./node_modules/react-simplemde-editor/lib/index.js
Module not found: Error: Can't resolve 'babel-runtime/helpers/inherits' in '/home/nathan/code/bath-north-labour/node_modules/react-simplemde-editor/lib'
 @ ./node_modules/react-simplemde-editor/lib/index.js 25:17-58
 @ ./distribution/app/components/views/page.js
 @ ./distribution/app/components/app.js
 @ ./distribution/app/client.js

ERROR in ./node_modules/react-simplemde-editor/lib/index.js
Module not found: Error: Can't resolve 'babel-runtime/helpers/possibleConstructorReturn' in '/home/nathan/code/bath-north-labour/node_modules/react-simplemde-editor/lib'
 @ ./node_modules/react-simplemde-editor/lib/index.js 21:34-92
 @ ./distribution/app/components/views/page.js
 @ ./distribution/app/components/app.js
 @ ./distribution/app/client.js

ERROR in ./node_modules/react-simplemde-editor/lib/index.js
Module not found: Error: Can't resolve 'babel-runtime/helpers/typeof' in '/home/nathan/code/bath-north-labour/node_modules/react-simplemde-editor/lib'
 @ ./node_modules/react-simplemde-editor/lib/index.js 5:15-54
 @ ./distribution/app/components/views/page.js
 @ ./distribution/app/components/app.js
 @ ./distribution/app/client.js

Can I take over the project?

Hi, I quite often use this editor, and I want to keep it up. So it will be at least compatible with React 16 etc. So, @benrlodge if you fine with that, I would like to take care of it so I can merge PRs, update it myself etc.

previewRender should allow a react component as return value

Hello,
I tried to integrate this in a project where we use react-markdown and would like to use the ReactMarkdown Component in previewRender to keep preview and live rendering consistent - sadly previewRender expects a string as far as i can see. So sth like:

<SimpleMDE
          value={this.state.text}
          onChange={this.setText}
          options={{
            previewRender (text) {
              return <ReactMarkdown
                source={text}
                renderers={{
                  CodeBlock: CodeRenderer,
                  Code: CodeRenderer
                }}
              />
            }
          }}
        />

is currently not possible.

The editor is totaly broken in my react/webpack project

I try to use the component in my project. I am following the Usage guide and the only thing I see are unstyled toolbar buttons.
There are also no errors/warnings in the console, so I have no idea what is wrong.

This is my setup:

  "devDependencies": {
    "babel-core": "^6.25.0",
    "babel-loader": "^7.1.1",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-2": "^6.24.1",
    "react-hot-loader": "^1.3.1",
    "webpack": "^3.0.0",
    "webpack-dev-server": "^2.5.0"
  },
  "dependencies": {
    "react": "^15.6.1",
    "react-dom": "^15.6.1",
    "react-simplemde-editor": "^3.6.11"
  }

Add license

Can we consider licensing this under the MIT license so other projects can make use of it? :)

How can I get and set the cursor position?

It would be really awesome if I could get and then set the cursor position, or at least change the default behavior so that the cursor would be at the end of the text, not the begninning.

Can you help me out?

Problems setting value if redirected from router.

I have administration tool for admin Blogposts. When I press from it Edit, It's redirect me there via component via React-Router. And value suppose to be set from state of the smart component by passing it down to the dumb component, which contain SimpleMdeEditor.
Problem is that value is not passing down from constructor or whatever and I forced to call setState in componentDidMount to get value rendered in SimpleMdeEditor, btw simple inputs are work just fine without cDM call. Here is the code snippet.
Smart component. (Container component)

//Imports there

class EditPostPage extends React.Component {

  constructor(props, context) {
    super(props, context);

    this.state = {
      post: Object.assign({}, props.post),
      errors: {},
      saving: false
    };

    this.updatePostState = this.updatePostState.bind(this);
    this.handleEditorChange = this.handleEditorChange.bind(this);
    this.savePost = this.savePost.bind(this);
  }

//Forced to do so, linter are getting crazy :P
  componentDidMount() {
    this.setState({post: objectAssign({}, this.props.post)}); // eslint-disable-line
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.post.id != nextProps.post.id) {
      // Necessary to populate form when existing author is loaded directly.
      this.setState({post: Object.assign({}, nextProps.post)});
    }
  }

//Some skipped code

  handleEditorChange(value) {
    return this.setState({post: objectAssign(this.state.post, {body: value})});
  }

  render() {

    return (
      <EditPostForm post={this.state.post}
                    saving={this.state.saving}
                    errors={this.state.errors}
                    onChange={this.updatePostState}
                    handleEditorChange={this.handleEditorChange}
                    onSave={this.savePost}
      />
    );
  }
}

//mapStateToProps etc. is there.

Dumb stateless component

const EditPostForm = ({saving, onSave, post, onChange, errors, handleEditorChange}) => {
  return (
    <form>
      {post.id == '' ? <h1>Create post</h1> : <h1>Edit post</h1>}

      <TextInput
        name="title"
        label="Title"
        value={post.title}
        onChange={onChange}
        error={errors.title}
      />
      <SimpleMDE onChange={handleEditorChange} value={post.body} options={{
        autofocus: true,
        spellChecker: false
      }}/>
      <input
        type="submit"
        disabled={saving}
        value={saving ? 'Saving...' : 'Save'}
        className="btn btn-primary"
        onClick={onSave}
      />
    </form>
  );
};

Hope that I explain it nicely.

refresh method

Is there a refresh method that I can use? Like the one in the jquery version this.mde.codemirror.refresh()

Issue trying to set value

Hello, first of all congratz on the great work you've got so far.
My issue is that currently I can't set the value to any value, even with the demo's code.

Here's my code

import React from "react";
import ReactMarkdown from 'react-markdown';
import SimpleMDEReact from 'react-simplemde-editor';

export default class PostContent extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
          textValue1: "I am the initial value. Erase me, or try the button above."
        }
    }

    changed(value) {
        alert(value);
    }

    handleChange1(value) {
      this.setState({
        textValue1: value
      });
    }

    render() {
        if (!this.props.edit)
            return (<ReactMarkdown source={this.props.post.Text}/>)
        else
            return (<SimpleMDEReact options={{value: this.state.textValue1}} />)
    }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.