Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nimble Rich Text Editor and Viewer Spec Document #1289

Merged
merged 45 commits into from
Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
f14ee94
Initial nimble spec of the rich text editor and viewer component
vivinkrishna-ni Jun 8, 2023
8362d19
Corrected the header name of the spec
vivinkrishna-ni Jun 8, 2023
b22cbb7
Change files
vivinkrishna-ni Jun 8, 2023
129dcf1
Updated the supported features in feature section.
vivinkrishna-ni Jun 8, 2023
4e5ff60
Resolved some of the PR comments
vivinkrishna-ni Jun 8, 2023
217e4f1
Removed few methods as it is not required.
vivinkrishna-ni Jun 8, 2023
a95970b
Resolve some of the PR comments
vivinkrishna-ni Jun 8, 2023
a26b2a4
Updated the template for rich text editor
vivinkrishna-ni Jun 8, 2023
d9abc1d
Resolved some of the PR comments and made update to some design changes.
vivinkrishna-ni Jun 9, 2023
acd0f22
Resolving PR comments on updating the doc on implementation and secur…
vivinkrishna-ni Jun 9, 2023
7251bba
Corrected the sentence in non goals section
vivinkrishna-ni Jun 9, 2023
3e03f12
Corrected the sentence in API section.
vivinkrishna-ni Jun 9, 2023
b8ed166
Spell check in the implementation part.
vivinkrishna-ni Jun 9, 2023
a11e16f
Sentence correction in accessability.
vivinkrishna-ni Jun 9, 2023
e9ea50d
Made few changes to doc as suggested
vivinkrishna-ni Jun 9, 2023
3727587
noreply email update
vivinkrishna-ni Jun 11, 2023
2e5c8c5
Resolved some of the PR comments in rich-text-editor and viewer spec
vivinkrishna-ni Jun 12, 2023
afa0744
Corrected minor changes.
vivinkrishna-ni Jun 13, 2023
6eb5829
Updated the title of the viewer
vivinkrishna-ni Jun 13, 2023
c831c23
Updated a point in the API events section
vivinkrishna-ni Jun 13, 2023
056e664
Updated the spec images as per the new mockup screens
vivinkrishna-ni Jun 13, 2023
c2d64ba
Added CSS design for both editor and viewer component
vivinkrishna-ni Jun 13, 2023
429d3b0
Resolved minor corrections in the spec
vivinkrishna-ni Jun 13, 2023
ecb1890
Updated the comments UI mockup link
vivinkrishna-ni Jun 13, 2023
455d8a6
Corrected the risks and challenges points
vivinkrishna-ni Jun 13, 2023
ad6eca5
Updated the template and made few corrections in CSS design
vivinkrishna-ni Jun 14, 2023
35a9b5b
Updated the description in Non-goals section
vivinkrishna-ni Jun 14, 2023
9aee11f
Made few changes to the spec.
vivinkrishna-ni Jun 14, 2023
539b01d
Updated the API section for both the components
vivinkrishna-ni Jun 14, 2023
c7a75d0
Resolved some of the corrections in the spec
vivinkrishna-ni Jun 15, 2023
a09401f
Resolved some of the PR comments
vivinkrishna-ni Jun 15, 2023
1d86bf6
Updated the API to check the isEmpty value
vivinkrishna-ni Jun 15, 2023
f3d834d
Updated the styling part of the component
vivinkrishna-ni Jun 15, 2023
f0049d3
Updated the style information for viewer component.
vivinkrishna-ni Jun 15, 2023
1651461
Updated the package size information to the dependencies
vivinkrishna-ni Jun 16, 2023
2490c80
Updated the spec as per the suggestion.
vivinkrishna-ni Jun 19, 2023
9c89946
Updated the spec
vivinkrishna-ni Jun 19, 2023
1a4191a
Merge branch 'main' into rich-text-editor-viewer-spec
vivinkrishna-ni Jun 19, 2023
6cfd408
Merge branch 'main' into rich-text-editor-viewer-spec
vivinkrishna-ni Jun 21, 2023
92025d3
Updated the sizing changes for editor and viewer component.
vivinkrishna-ni Jun 21, 2023
d75a1a3
Resolved linting errors
vivinkrishna-ni Jun 21, 2023
bff8d5b
Added information on the Angular implementation
vivinkrishna-ni Jun 22, 2023
53841a7
Merge branch 'main' into rich-text-editor-viewer-spec
vivinkrishna-ni Jun 23, 2023
7007a3b
Updated the spec by removing the hyperlink support for the initial re…
vivinkrishna-ni Jun 26, 2023
4a10729
Merge branch 'main' into rich-text-editor-viewer-spec
vivinkrishna-ni Jun 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "none",
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
"comment": "Add spec document for nimble rich text editor and nimble rich text viewer",
"packageName": "@ni/nimble-components",
"email": "[email protected]",
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
"dependentChangeType": "none"
}
335 changes: 335 additions & 0 deletions packages/nimble-components/src/rich-text-editor-viewer/specs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,335 @@
# Nimble Rich Text Editor and Nimble Rich Text Viewer
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved

## Overview

- The `nimble-rich-text-editor` component is a text editing tool that offers a comprehensive range of functionalities for
incorporating rich text content. It provides users with the ability to apply different text styles and formats to their content.
- The `nimble-rich-text-viewer` component is way to view all the rich text content.

### Background

vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
[Nimble issue #1288](https://github.com/ni/nimble/issues/1288)

[Comments UI mockup](https://www.figma.com/file/Q5SU1OwrnD08keon3zObRX/SystemLink?type=design&node-id=6280-94045)

vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
### Non-goals

- The visual and interaction design for `nimble-rich-text-editor` and `nimble-rich-text-viewer` is out of scope for this spec component.
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
- Blazor integration will be out of scope for this component as we have less or no experience in Blazor component development or other
related technology. Blazor example app addition will also be not covered in this spec.
- Adding an example Angular client application for this component may not be included in the initial releases. However, the integration
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
jattasNI marked this conversation as resolved.
Show resolved Hide resolved
of the rich-text-editor with Angular applications, achieved through a directive, will be developed following the completion of this
component.

### Features
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved

The `nimble-rich-text-editor` supports the basic text formatting options that includes:

1. Bold
2. Italics
3. Strikeout
4. Numbered List
5. Bulleted List

This component will also offer APIs and interactive methods to format texts in the following ways:

1. Using the buttons located below the editor to modify the text formatting for the selected texts.
2. Using the keyboard shortcuts to modify the text formatting in the editor.
3. Support to get markdown output from the editor.
4. Support to convert the markdown to HTML to render it back in the `nimble-rich-text-viewer` component.

#### _Additional features out of scope of this spec_

- Allowing the user to tag or mention by entering `@` in the editor and selecting the user name from the drop-down list.
- Support for adding images to the editor either by uploading or by pasting it.
- Support for adding hyperlinks to the existing words in the editor. However, adding raw links by pasting to the editor is supported.
- Support for underlining the text.
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
- Provide APIs to make the buttons in the toolbar located below the editor to be hidden or disable.
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved

### Risks and Challenges

- Visual design and interaction design for both the components are out of scope for the initial release. We will start with the existing
[mockup screens](https://www.figma.com/file/Q5SU1OwrnD08keon3zObRX/SystemLink?type=design&node-id=6280-94045) which is designed for
comments feature. At this moment, we cannot afford to cover all the corner case of visual design specs but we managed to refer from
other visual designs and try to incorporate with the nimble standards.
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
- Due to the immediate requirement for GM (`Comments Feature`), we are not adding any additional enhancements or feature requirements
apart from the mentioned features in the initial release.
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
- The mobile view of the component has not been designed yet, and we are actively collaborating with the design team to create basic mockup screens. We will
update this spec accordingly as progress is made.
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved

### Prior Art/Examples

Sample Mockup Screenshots

_`nimble-rich-text-editor`_

![Editor](./spec-images/editor-sample.png)

_`nimble-rich-text-viewer`_

![Viewer](./spec-images/viewer-sample.png)
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved

## Design

_nimble-rich-text-editor_
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved

The `nimble-rich-text-editor` will be divided into two sections namely an `editor` section and a `footer` section.

1. `editor` section is the actual text area to add or update rich text contents.
2. `footer` section consists of `nimble-button` to control each text formatting functionalities like bold, italic etc,. and a
`footer-actions` slot element which is typically used to add action buttons to the right bottom of the component.

Here is the basic high level template used in this component:
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved

```html
<template>
<section>
<div id="editor"></div>
</section>
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
<footer>
<div id="toolbar">
<nimble-button></nimble-button>
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
</div>
<div>
<slot name="footer-actions"></slot>
</div>
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
</footer>
</template>
```

An example usage of the `nimble-rich-text-editor` in the application layer is as follows:

```html
<nimble-rich-text-editor>
<div slot="footer-actions">
<nimble-button>Cancel</nimble-button>
<nimble-button>Add Comment</nimble-button>
</div>
</nimble-rich-text-editor>
```

_nimble-rich-text-viewer_

The `nimble-rich-text-viewer` is used for viewing rich text content when markdown string is passed to it. It performs the post-processing
tasks to convert the markdown string to corresponding HTML nodes for each text formatting.

### API

#### `nimble-rich-text-editor`

_Props/Attrs_

- none

_Methods_

- `setMarkdown()` - sets the markdown input from the consumer component to preload the content in the editor.
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
- `getMarkdown()` - gets the processed markdown output from the component.
- [`destroy()`](https://tiptap.dev/api/editor#destroy) - stops the editor instance and unbinds all events.
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
- [`isEmpty()`](https://tiptap.dev/api/editor#is-empty) - obtains a boolean value indicating whether the editor is empty or not.
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved

_Events_

- `onChange` - event emitted when there is a change in the the editor. This can be achieved through tiptap's
[transaction event](https://tiptap.dev/api/events#transaction).
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved

_CSS Classes and CSS Custom Properties that affect the component_

- none
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved

#### `nimble-rich-text-viewer`

_Props/Attrs_

- `markdown-value`: string - markdown input to the component to render it in the text viewer.
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved

_Methods_

- none

_Events_

- none

_CSS Classes and CSS Custom Properties that affect the component_

- none

### Anatomy

#### `nimble-rich-text-editor`

_Slot Names_

- `footer-actions`:
1. It is a container that allows a client to easily place buttons at the right bottom of the component to interact with the editor.
2. If no content is slotted in the footer-actions, the element will be emptied and shrunk to accommodate buttons from the
toolbar.
3. If content is slotted in the footer-actions, it will occupy a maximum of thirty percent of the entire horizontal footer. If
there are additional elements beyond this limit, they will be positioned below within the same footer-actions container.

_Note_: The positioning of these slot elements in the mobile view of the component has not yet been confirmed.

_Host Classes_

- none

_Slotted Content/Slotted Classes_

- none

_CSS Parts_

- none

### Angular integration

An Angular directive will be created for both components. The components will not have form association, so a `ControlValueAccessor` will
not be created.

### Blazor integration

A Blazor wrapper will not be created for the component.

### Visual Appearance

NA
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved

## Implementation

We have chosen to utilize the [`Tiptap`](https://tiptap.dev/) rich text editor as the underlying third-party library for developing the
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
`nimble-rich-text-editor`. This decision was made due to its extensive range of customization options over other third party libraries for
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
rich text editing and it is the ideal choice for meeting our specific use cases and some are mentioned below:

1. Includes all [basic functionalities](https://tiptap.dev/) like bold, italics, numbered and bulleted lists etc.
2. Includes support to work seamlessly inside the `shadow root`.
3. [Tiptap](https://tiptap.dev/introduction) is built on top of ProseMirror and so have access to all the powerful APIs provided by
ProseMirror through [`@tiptap/pm`](https://tiptap.dev/guide/prosemirror).
4. Includes support to render the content of the editor with markdown input.
5. Includes support to retrieve the content of the editor as HTML and Markdown output (using
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
[prosemirror-markdown](https://github.com/ProseMirror/prosemirror-markdown)).
6. Includes extensions to support [@mention](https://tiptap.dev/api/nodes/mention) functionality (Future scope).

The `nimble-rich-text-editor` is initialized by creating an instance of the [Editor](https://tiptap.dev/api/editor#introduction) class from
the Tiptap's core library. With that we have access to all the APIs exposed, by utilizing some of their extensions like
[StarterKit](https://tiptap.dev/api/extensions/starter-kit) which is a collection of most popular Tiptap extensions includes bold, italics
and all other basic rich text formatting options. All these options([marks](https://tiptap.dev/api/marks)) can also be accessed individually.
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved

The rich text content entered in the editor is converted to markdown output using `prosemirror-markdown` serializer. Here is the reference for basic formatting
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
syntax in markdown:

- Bold - `**Bold**`
- Italics - `*Italics*`
- Strikeout - `~~Strikeout~~`
- Numbered list - `1. Numbered list`
- Bulleted list - `* Bulleted list`

The `nimble-rich-text-viewer` will be responsible for converting the input markdown string to a HTML Fragments with the help of
`prosemirror-markdown` parser, which then converted to HTML string and rendered into the component to view all rich text content.
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved

### Prototype

[`Tiptap prototype in Stackblitz`](https://stackblitz.com/edit/typescript-g3yfmo?file=index.ts)
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved

The prototype includes the below functionalities,

1. Basic formatting support.
2. Image support. - The prototype includes [`Tiptap Extension`](https://tiptap.dev/api/nodes/image) to support images.
3. `@mention` support. - The prototype includes default user list that gets triggered using `@` character.
4. Markdown support. - The prototype includes support to render/retrieve content in markdown format.
5. `Shadow root` support - The prototype uses [Microsoft Fast](https://github.com/microsoft/fast) to create the rich text editor as a
custom component that renders in the shadow root.
6. `Top layer` support - Hyperlink using `nimble-dialog` which renders the popup in top layer.

### States

_Button State_

The buttons in the toolbar will indicate the formatting status of the selected text in the editor. For example, if the text in the editor
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
is bold and the cursor is placed on the text, the bold button will be indicated as a active state. The active state is indicated as `block`
appearance of the [`nimble-button`](https://nimble.ni.dev/storybook/?path=/docs/button--docs) and inactive state is in `ghost`
appearance. Refer the below sample screenshot with active bold state.

![Bold Button State](./spec-images/button-state.png)

### Accessibility

[Tiptap Accessibility](https://tiptap.dev/guide/accessibility)

_Focus_

- Focus state of the editor will be the same as the `nimble-text-area`.
- Focus state of the buttons will be the same as the `nimble-button`.

_Keyboard accessibility and shortcuts for text formatting_

All the basic keyboard accessibility for the tiptap rich text editor is mentioned in their
[keyboard shortcut](https://tiptap.dev/api/keyboard-shortcuts#predefined-keyboard-shortcuts) page. To facilitate easy access, listed down
the supported text formatting's keyboard shortcuts in the table below.

| Key | Behavior |
| ----------------------- | -------------------------------------------------------- |
| Tab | To reach the editor |
| Shift + Arrow keys | To select the group of texts in the editor |
| Ctrl + B | To make the selected text bold |
| Ctrl + I | To make the selected text italic |
| Ctrl + Shift + X | To strikeout the selected text |
| Ctrl + Shift + 7 | To enable the focused paragraph a numbered list |
| Ctrl + Shift + 8 | To enable the focused paragraph a bulleted list |
| Tab (For lists) | To create a sub point within a bulleted or numbered list |
| Shift + Tab (For lists) | To remove a sub point from a bulleted or numbered lists |

_Keyboard navigation with toolbar buttons focused_
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved

| Key | Behavior |
| ------------ | ------------------------------------------------------------------------------ |
| Space, Enter | Enable the selected text formatting feature and return the focus to the editor |
| Shift + Tab | To reach the editor back to focus |
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved

_Note_: All other keyboard interaction determined by the slotted element will not be defined in this document.

### Globalization

Currently, this component does not have any string data to be localized. In the footer menu for text formatting, only icons will be displayed. However,
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
strings may be used for tooltips to enable localization, which will be managed through the `nimble-tooltip` component.

### Security

- none
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved

### Performance

Performance of tiptap explained in an example of having [long texts](https://tiptap.dev/examples/book).

### Dependencies

This component is dependent on the [`tiptap`](https://tiptap.dev/) third party library. As mentioned,
[tiptap](https://tiptap.dev/introduction#why-should-i-use-tiptap) is built on top of prosemirror, we might also use some of the prosemirror's
library. For the currently supported features, we will include the following libraries that will be added to the packages.json

- @tiptap/core
- @tiptap/pm
- @tiptap/starter-kit

**_Note_**: For markdown parser and serializer, [prosemirror-markdown](https://github.com/ProseMirror/prosemirror-markdown) internal dependencies will be installed along with this.

### Test Plan

The current testing plan involves writing unit tests to verify the core functionality of the component. All tests for this component will
follow the standards set by the nimble repository, which include unit tests to assess component logic and Chromatic tests to cover all
visual states of the component.

### Tooling

_Are there any special considerations for tooling? Will tooling changes need to be made? Is there a special way to light up this component
vivinkrishna-ni marked this conversation as resolved.
Show resolved Hide resolved
in our tooling that would be compelling for developers/designers?_

### Documentation

As with other nimble components, a story will be added in storybook for the new component. Relevant documentation will be added there.

---

## Open Issues

- none
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.