question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

You can follow along with the development of this the new API on the next branch.

Project History

Originally, remirror was built as a fun side project; a challenge to myself to see if I could create an extensible editor for React. It was inspired by the implementations of slate, draftjs, tiptap and @atlaskit/editor. I hoped to create something with great performance, excellent built in plugins, and popular prebuilt editors for easier consumption.

It turned out, several people had started to bump into some problems of the currently available editors and looked to remirror as a solution. Although happy with the interest, I was also aware of the limitations of remirror. While I wanted to push forward with some of my initial plans, I quickly bumped into limitations. I just couldn’t justify the time needed to work on the project at the expense of actual paid work. It started to look like remirror would become a project which died before it had ever had the chance to truly live.

Recently, the situation has changed. I am now able to divert more of my attention to reworking the API and integrating the project into an ambitious startup seeking to build their realtime collaboration hub with remirror. They see the potential of this project and have chosen to back it in the most amazing way.

Changes

The rest of this post will outline what changes are coming soon.

Documentation first approach

A new documentation first approach will be taken to developing the next version of remirror. The docs site will be rebuilt with this in mind.

Currently documentation is almost non-existent. This is true even for some of the most basic features. With the incoming changes to the API, it feels like a perfect time to address this situation.

The priority is adding detailed documentation around:

  • Creating a new editor from scratch.
  • Creating the editor as a controlled component.
  • Using the editor packages (e.g. @remirror/editor-social).
  • Detailed instructions on each standalone extension - @remirror/extension-*.
  • Styling the editor.

New design principles

  • Make it feel like React
    • Users shouldn’t ever need to be aware that under the hood we are using a dom based library (prosemirror).
  • Don’t surprise the user
    • Similar to the above, there should be no edge cases where the user is forced to exit from the expected React paradigm.
  • Treat TypeScript as a first class citizen.
    • This library will always be useable with JavaScript but it should aim for an incredible TypeScript user experience.
    • Auto completions, auto suggestions, and first class inline documentation.
    • Like an invisible hand the types should make the user feel like they’re being guided to the right solution.
  • Avoid magic.
    • Avoid magic strings or concepts that solve one problem but increase complexity of the API namespace.
  • Keep the API namespace small.
    • There should be one way to accomplish a task.
    • Right now there is a ManagedRemirrorProvider, a RemirrorProvider, a RemirrorManager. As a first time user of the library this is very confusing. Reduce the namespace. Make it possible to do things in a well tested and simple to understand way.

Improved Core API

Improved configuration

EDIT: The following was replaced with a single Options interface which can be configured as explained in the updated docs.

~The configuration of each extension will be split into two parts.~

  • ~config~ - Options which update the schema and core functionality of the editor.
    • e.g. an option which updates the types of content accepted by a NodeExtension would be a config option since a change would require the entire editor to be updated and any now invalid contents to be removed or updated.
  • ~props~ - Options which are only used during the runtime operations.
    • e.g. most callbacks will fall under this option. The MentionExtension has onChange and onExit options which will become props since they are only called after the editor has been inserted into the DOM.

No exposed class

Classes will be removed from the public API. You will never need to use class SimpleExtension extends Extension { or new SimpleExtension(). There will be a better API for creating extensions. This will avoid the issues that can crop up when classes are extended in compiled code which uses functions to represent classes.

import { BaseExtensionConfig } from '@remirror/core';

interface Config extends BaseExtensionConfig {}
interface Props {
  message: string;
}

// Create an extension which logs on the `enter` key being pressed.
// There are three extensions `plain` | `node` | `mark` and the extension creator allows for the creation of all three.
const LogWhenEnterKeyExtension = ExtensionCreator.plain<Config, Props>({
  name: 'logWhenEnterKey',
  defaultConfig: {},
  defaultProps: { message: 'No message defined' },
  keys: ({ config, props }) => ({
    Enter: () => {
      console.log(props.message);
      return true; // Also runs the next action.
    },
  }),
});

// Creates the extension instance which can be used within the editor.
const logWhenEnterKey = LogWhenEnterKeyExtension.of({ message: 'enter key pressed' });

EDIT: The above was abandoned. While it would be nice to hide the classes from the public API, it wasn’t possible to do this in a way that also met another key goal of First Class Typescript Support. Without classes every part of the object that can be configured needs to be assigned a generic parameter. I had started with this approach, but once I reached 7 generic parameters I realised it was becoming unmanageable.

With TypeScript classes are types. This means that the class can have properties inferred at any time after declaration. Objects and functions don’t have that luxury. The type must be declared upfront.

I’ll write a blog post as to why I took this decision later on.

Improved React API

This builds on the post from @benjie.

@remirror/react API will be simplified to only include the following exports (not including types).

  • <RemirrorProvider extensionManager={extensionManager} /> - Injects the editor context into the sub components.
  • useRemirror() - Retrieves the remirror context when used within a component wrapped by the RemirrorProvider. It provides utilities like getRootProps which is a function that should be called to decide the root dom element for the prosemirror editor.
  • useExtension(Creator: ExtensionConstructor, options: OptionsFrom<ExtensionConstructor>): Extension
  • useManager(lazyCreator: () => Extension[], settings?: ManagerSettings) - Configure the RemirrorManager which takes a function that returns a list of extensions as the first parameter and all manager related settings as the second parameter.

As a result hooks will be the preferred way for configuring React editors.

The following is an example of how a small editor with bold and italic support would be set up.

import { BoldExtension, ItalicExtension } from '@remirror/core-extensions';
import { RemirrorProvider, useManager, useExtension } from '@remirror/react';

// Set up the component to provide the functionality for the editor
const SmallEditor = () => {
  const { getRootProps, commands } = useRemirror(); // Picked from the context.
  
  // Configure the extension options
  useExtension(BoldExtension, { weight: '800' }); 

  <div>
    <button onClick={() => commands.bold()}>bold<button>
    <button onClick={() => commands.italic()}>italic<button>
    <div {...getRootProps()} />
  </div>
};

const SmallEditorWrapper = () => {
  const extensionManager = useManager(() => [new ItalicExtension(), new BoldExtension]);

  return (
    <RemirrorProvider extensionManager={extensionManager}>
      <SmallEditor />
    </RemirrorProvider>
  );
};

For more information on how the API will feel in a more complex setup see this comment by @benjie.

Styling

Currently, there are a several @remirror/ui-* packages which were meant to make styling of the API much easier. Unfortunately due to a lack of documentation this has not really materialized and right now the packages are very confusing.

Work and thought is still going into how this can be made better and I’ll update this section when more is known.

EDIT: Styling is now available via, CSS, emotion, styled-components and pure dom manipulation. You can choose which you prefer based on your project.

Development playground

Similar to TypeScript, babel and other prominent libraries it’s important to have a playground which speeds up development and provides a way to explore the features of remirror.

The playground will allow users to:

  • Swap out different extensions to see their impact.
  • Try different editors and mix and match functionality.
  • Shareable playgrounds for reproducing bugs and sharing designs.
  • Export TypeScript code for implementing the created editors in their projects.

Serialization and deserialization

The question on how to persist the data produced by remirror is one that often comes up in the issues. This is something that I would like to address in the next version.

Collaboration

One of the main selling points of Prosemirror is the focus on a consumable collaboration effort. This has been made a priority and will be addressed in the next version.

Improved commands

Right now commands are methods that run on the prosemirror state and dispatch a transaction. They return true when successful and false when otherwise. The next version of the API will provide an abstraction for the commands which allows for chaining.

Chaining

// Within the `RemirrorProvider` Context.

const { chain } = useRemirror();
chain
  .insertText('hello')
  .selectAll()
  .bold()
  .run(); // Run executes the commands

Task List

Core

  • Create a todo list of what needs to change.
  • Create new documentation site.
    • Add details on how to contribute to the next branch.
    • Write up the new API and what will change.
  • Create new playground package.
    • Add /playground url to the docs site.
    • Add playground page to storybooks and update the contributing guide.
    • Add tests for the playground
  • Update to new classless api (internally classes can be used but externally no)
    • ~Split up options into config and props.~
    • ~Create new class factories and decide on type inference mechanics.~
    • Update all extensions to the new API
  • Move over to the new hooks API
    • Remove old API methods (deprecate them in the main branch).
    • Add new hooks methods

Other

  • Refactor e2e tests from puppeteer to playwright.
  • Refactor build process.
  • Split up ci builds into multistep process and test for supported node versions.
  • Add playground persistent urls for reporting bugs or requesting features.
  • Integrate sherlock for verifying bugs.
  • Enable code generation from playground.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:29
  • Comments:16 (10 by maintainers)

github_iconTop GitHub Comments

10reactions
ifiokjrcommented, May 29, 2020

I’m tentatively targeting feature parity (with the current master) in prerelease within 4 - 5 weeks (~21st - 28th~ ~Apr~ ~May~ 5th - 12th June). After that it’s all about how many bugs surface before the final 1.0.0 release.

I don’t want to rush that stage to avoid the need for drastic API changes in the future.

Also, I really like what you’re doing with https://github.com/webclipper/web-clipper. It looks lovely.

Edit - Updated months from April to May Edit - Updated 28th May to 12th June

4reactions
ifiokjrcommented, Jul 15, 2020

@ted-mccarthyfinch glad to hear you’re excited. I’ll be putting a starter pack together soon, hopefully tomorrow.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Next Official Site: Online Fashion, Kids Clothes & Homeware
Shop the latest women's, men's & children's fashion plus homeware, beauty, designer brands & more. Next day delivery & free returns available. Shop...
Read more >
Next US
Shop the latest women's, men's and children's fashion plus homeware, beauty and more. Next day delivery and free returns available. Shop now!
Read more >
Next (2007) - IMDb
A Las Vegas magician who can see into the future is pursued by FBI agents seeking to use his abilities to prevent a...
Read more >
Next Direct
Shop Worldwide. United Kingdom · Israel · Germany · Ireland · Saudi Arabia · Australia · United Arab Emirates · Ukraine. Americas. Argentina....
Read more >
NeXT - Wikipedia
NeXT, Inc was an American technology company that specialized in computer workstations intended for higher education and business use.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found