Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions demo/src/components/Playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ export const Playground = memo<PlaygroundProps>((props) => {
table_ignoreSplittersInBlockMath: true,
table_ignoreSplittersInInlineCode: true,
table_ignoreSplittersInInlineMath: true,
cellBackground: true,
},
...wysiwygConfig?.extensionOptions,
},
Expand Down
191 changes: 0 additions & 191 deletions demo/src/defaults/content.ts
Original file line number Diff line number Diff line change
@@ -1,169 +1,6 @@
export const markup = `
&nbsp;

Welcome to the editor! Start typing the character \`/\`

![Markdown Editor](https://github.com/user-attachments/assets/0b4e5f65-54cf-475f-9c68-557a4e9edb46 =700x)

## Markdown WYSIWYG and markup editor

MarkdownEditor is a powerful tool for working with Markdown, which combines WYSIWYG and Markup modes. This means that you can create and edit content in a convenient visual mode, as well as have full control over the markup.

The editor supports following formats:

* WYSIWYG

* markup

Click on the gear in the upper right corner to change the mode and see the \`md\` markup.

### Various blocks included

{% cut "Combine different blocks" %}

{% note info "Block for notes, tips, warnings, and alerts" %}

Depending on the content, notes with different titles and formats are used:

* Note: provides additional information.
* Tip: offers a recommendation.
* Warning: issues a warning.
* Alert: indicates a restriction.

{% endnote %}

> [Improve](https://github.com/gravity-ui/markdown-editor/blob/main/docs/how-to-add-preview.md) the editor interface
>
> *improved by you*

{% endcut %}

Or write your extension using a [convenient api](https://github.com/gravity-ui/markdown-editor/blob/main/docs/how-to-create-extension.md)

### A user-friendly API is provided

Easily connect to your React app with a hook:

\`\`\`plaintext
import React from 'react';
import { useMarkdownEditor, MarkdownEditorView } from '@gravity-ui/markdown-editor';
import { toaster } from '@gravity-ui/uikit/toaster-singleton';

function Editor({ onSubmit }) {
const editor = useMarkdownEditor({ allowHTML: false });

React.useEffect(() => {
function submitHandler() {
// Serialize current content to markdown markup
const value = editor.getValue();
onSubmit(value);
}

editor.on('submit', submitHandler);
return () => {
editor.off('submit', submitHandler);
};
}, [onSubmit]);

return <MarkdownEditorView stickyToolbar autofocus editor={editor} />;
}
\`\`\`

### Convenient UX control is equipped

#### Hot keys

{% list tabs %}

- WYSIWYG mode



|Formatting|Windows Shortcut|Mac OS Shortcut|
|:---|:---|:---|
|Bold text|Ctrl \\+ B|⌘ \\+ B|
|Italic|Ctrl \\+ I|⌘ \\+ I|
|Underlined text|Ctrl \\+ U|⌘ \\+ U|
|Strikethrough text|Ctrl \\+ Shift \\+ S|⌘ \\+ Shift \\+ S|

- Markup mode



|Formatting|Markup|Result|
|:---|:---|:---|
|Bold text|\`**Bold**\`|**Bold**|
|Italic|\`*Italic*\`|*Italic*|
|Underlined text|\`++Underlined++\`|++Underlined++|
|Strikethrough text|\`~~Strikethrough~~\`|~~Strikethrough~~|

{% endlist %}

#### Context menu

Select this text and you will see **a context menu**.

#### Auto-conversion

Quickly create blocks by entering characters that will be replaced by blocks. For example, the automatic conversion of \`-\` and space creates a list, \`>\` and space creates a quote. Try it out.

---

### Current and future features

[X] Some already finished things

[ ] VS Code plugin

[ ] Mobile version

### And a multitude of other functionalities :sweat_smile: :fire:

See <https://github.com/gravity-ui/markdown-editor>

# More examples {#anchor}

{% cut "Headings" %}

# Heading 1

## Heading 2

### Heading 3

#### Heading 4

##### Heading 5

###### Heading 6

{% endcut %}

{% cut "This is a cut heading" %}

**A** *here* ~~it~~ ++is awesome++ ^c^~o~^n^~t~^e^~n~^t^

> Done deal - deal done \`(quote)\`

{% endcut %}

{% cut "Formulas" %}

This is an inline formula: $\\sqrt{3x-1}+(1+x)^2$

And here is a block formula:

$$f(\\relax{x}) = \\int_{-\\infty}^\\infty
\\hat f(\\xi)\\,e^{2 \\pi i \\xi x}
\\,d\\xi
$$

*Click on the formula to edit it*

{% endcut %}

---

#|
||

Expand Down Expand Up @@ -247,34 +84,6 @@ New approaches to learning in the digital age
||
|#

---

{% note info "Attention, please!" %}

* Thank

1. you

2. for

1. your

3. attention

* (nested lists)

> > > Quotes
> >
> > Nested
>
> As well

And ##monospace## can be **##com##**##bined\\*##

{% endnote %}

---

`.trim();

export const loremIpsum = `
Expand Down
1 change: 1 addition & 0 deletions demo/src/hocs/withLang.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {configure} from '@gravity-ui/uikit';
import type {Decorator} from '@storybook/react';

import '@gravity-ui/uikit/styles/styles.scss';
import '@gravity-ui/markdown-editor/styles/markdown.css'; // eslint-disable-line import/order

export const withLang: Decorator = (StoryItem, context) => {
const lang = context.globals.lang;
Expand Down
1 change: 1 addition & 0 deletions demo/src/hocs/withThemeProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {ThemeProvider} from '@gravity-ui/uikit';
import type {Decorator} from '@storybook/react';

import '@gravity-ui/uikit/styles/styles.scss';
import '@gravity-ui/markdown-editor/styles/markdown.css'; // eslint-disable-line import/order

export const withThemeProvider: Decorator = (StoryItem, context) => {
return (
Expand Down
1 change: 1 addition & 0 deletions demo/src/hocs/withToaster.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {toaster} from '@gravity-ui/uikit/toaster-singleton';
import type {Decorator} from '@storybook/react';

import '@gravity-ui/uikit/styles/styles.scss';
import '@gravity-ui/markdown-editor/styles/markdown.css'; // eslint-disable-line import/order

export const withToaster: Decorator = (StoryItem, context) => {
return (
Expand Down
82 changes: 82 additions & 0 deletions packages/editor/src/extensions/yfm/YfmTable/YfmTable.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {EditorState} from 'prosemirror-state';
import {builders} from 'prosemirror-test-builder';
import {EditorView} from 'prosemirror-view';
import dd from 'ts-dedent';

import {dispatchPasteEvent} from '../../../../tests/dispatch-event';
import {parseDOM} from '../../../../tests/parse-dom';
Expand Down Expand Up @@ -519,6 +520,87 @@ nested table
);
});

// TODO: enable when @diplodoc/transform >= 4.75.0 is released (parses ::{bg=...} cell attrs)
it.skip('should serialize cell-bg on first cell (same line as ||)', () => {
const markup = dd`
#|
|| ::{bg="info"}

cell11

||
|#

`.trimStart();

same(
markup,
doc(table(tbody(tr(td({[YfmTableAttr.CellBg]: 'info'}, p('cell11'), p('')))))),
);
});

it.skip('should serialize cell-bg on non-first cell (same line as |)', () => {
const markup = dd`
#|
||

cell11

|::{bg="warning"}

cell12

||
|#

`.trimStart();

same(
markup,
doc(
table(
tbody(
tr(
td(p('cell11'), p('')),
td({[YfmTableAttr.CellBg]: 'warning'}, p('cell12'), p('')),
),
),
),
),
);
});

it.skip('should serialize cell-bg on multiple cells', () => {
const markup = dd`
#|
|| ::{bg="info"}

cell11

|::{bg="danger"}

cell12

||
|#

`.trimStart();

same(
markup,
doc(
table(
tbody(
tr(
td({[YfmTableAttr.CellBg]: 'info'}, p('cell11'), p('')),
td({[YfmTableAttr.CellBg]: 'danger'}, p('cell12'), p('')),
),
),
),
),
);
});

it('should preserve cell-align', () => {
const markup = `
#|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ export enum YfmTableAttr {
Colspan = 'colspan',
Rowspan = 'rowspan',
CellAlign = 'data-cell-align',
CellBg = 'data-bg',
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export const getSchemaSpecs = (
[YfmTableAttr.Colspan]: {default: null},
[YfmTableAttr.Rowspan]: {default: null},
[YfmTableAttr.CellAlign]: {default: null},
[YfmTableAttr.CellBg]: {default: null},
},
parseDOM: [
{tag: 'td', priority: 200},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ export const serializerTokens: Record<YfmTableNode, SerializerNodeToken> = {
const rowspanStack: Record<number, number> = {};

tbody.forEach((trow) => {
state.write('||');
const firstCellBg = trow.firstChild?.attrs[YfmTableAttr.CellBg];
const firstCellAttrs =
typeof firstCellBg === 'string' ? ` ::{bg="${firstCellBg}"}` : '';
state.write(`||${firstCellAttrs}`);
state.ensureNewLine();
state.write('\n');

Expand All @@ -39,7 +42,9 @@ export const serializerTokens: Record<YfmTableNode, SerializerNodeToken> = {
}

if (colIndex > 0) {
state.write('|');
const cellBg = td.attrs[YfmTableAttr.CellBg];
const cellAttrs = typeof cellBg === 'string' ? `::{bg="${cellBg}"}` : '';
state.write(cellAttrs ? `|${cellAttrs}` : '|');
state.ensureNewLine();
state.write('\n');
}
Expand Down
14 changes: 13 additions & 1 deletion packages/editor/src/extensions/yfm/YfmTable/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ export type YfmTableOptions = YfmTableSpecsOptions & {
* @default true
*/
dnd?: boolean;
/**
* Enables cell background color picker for table cells.
* Available with @diplodoc/transform v4.75.0-beta0 or higher.
* @default false
*/
// TODO [MAJOR]: enable by default and remove option
cellBackground?: boolean;
};

export const YfmTable: ExtensionWithOptions<YfmTableOptions> = (builder, options) => {
Expand All @@ -47,7 +54,12 @@ export const YfmTable: ExtensionWithOptions<YfmTableOptions> = (builder, options
builder.addPlugin(yfmTableTransformPastedPlugin);

if (options.controls !== false) {
builder.addPlugin(yfmTableControlsPlugins({dndEnabled: options.dnd !== false}));
builder.addPlugin(
yfmTableControlsPlugins({
dndEnabled: options.dnd !== false,
cellBackground: options.cellBackground === true,
}),
);
}
};

Expand Down
Loading
Loading