Skip to content

Commit 568d46d

Browse files
authored
HtmlEditor: Markdown Support demo
1 parent 41477d6 commit 568d46d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+1389
-574
lines changed

apps/demos/Demos/HtmlEditor/OutputFormats/Angular/app/app.component.css renamed to apps/demos/Demos/HtmlEditor/MarkdownSupport/Angular/app/app.component.css

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
::ng-deep .dx-htmleditor-content img {
22
vertical-align: middle;
33
padding-right: 10px;
4+
margin-bottom: 22px;
5+
}
6+
7+
::ng-deep .value-title {
8+
font-size: var(--dx-font-size-sm);
9+
font-weight: 500;
410
}
511

612
::ng-deep .value-content {
713
margin-top: 20px;
814
overflow: auto;
9-
height: 110px;
10-
width: 100%;
15+
height: 210px;
1116
white-space: pre-wrap;
17+
border: 1px solid var(--dx-color-border);
18+
padding: 16px;
19+
background-color: var(--dx-color-main-bg);
1220
}
1321

1422
.options {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<dx-html-editor [height]="300" [converter]="converter" [(value)]="valueContent">
2+
<dxo-toolbar>
3+
<dxi-item name="undo"></dxi-item>
4+
<dxi-item name="redo"></dxi-item>
5+
<dxi-item name="separator"></dxi-item>
6+
<dxi-item name="bold"></dxi-item>
7+
<dxi-item name="italic"></dxi-item>
8+
<dxi-item name="separator"></dxi-item>
9+
<dxi-item
10+
name="header"
11+
[acceptedValues]="[false, 1, 2, 3, 4, 5]"
12+
[options]="{ inputAttr: { 'aria-label': 'Header' } }"
13+
></dxi-item>
14+
<dxi-item name="separator"></dxi-item>
15+
<dxi-item name="orderedList"></dxi-item>
16+
<dxi-item name="bulletList"></dxi-item>
17+
</dxo-toolbar>
18+
</dx-html-editor>
19+
20+
<div class="options">
21+
<div class="value-title"> Markdown Preview </div>
22+
<div class="value-content" tabindex="0">{{ valueContent }}</div>
23+
</div>

apps/demos/Demos/HtmlEditor/OutputFormats/Angular/app/app.component.ts renamed to apps/demos/Demos/HtmlEditor/MarkdownSupport/Angular/app/app.component.ts

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import { NgModule, Component, enableProdMode } from '@angular/core';
22
import { BrowserModule } from '@angular/platform-browser';
33
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
4-
import prettier from 'prettier/standalone';
5-
import parserHtml from 'prettier/parser-html';
6-
import { DxHtmlEditorModule, DxHtmlEditorTypes } from 'devextreme-angular/ui/html-editor';
7-
import { DxButtonGroupModule, DxButtonGroupTypes } from 'devextreme-angular/ui/button-group';
4+
import { DxHtmlEditorModule } from 'devextreme-angular/ui/html-editor';
85
import { Service } from './app.service';
96

7+
interface Converter {
8+
toHtml: (value: string) => string;
9+
fromHtml: (value: string) => string;
10+
}
11+
1012
if (!/localhost/.test(document.location.host)) {
1113
enableProdMode();
1214
}
@@ -27,32 +29,48 @@ if (window && window.config.packageConfigPaths) {
2729
export class AppComponent {
2830
valueContent: string;
2931

30-
editorValueType: DxHtmlEditorTypes.MarkupType = 'html';
32+
converter: Converter;
3133

3234
constructor(service: Service) {
3335
this.valueContent = service.getMarkup();
34-
}
35-
36-
onValueTypeChanged({ addedItems }: DxButtonGroupTypes.SelectionChangedEvent) {
37-
this.editorValueType = addedItems[0].text.toLowerCase();
38-
}
3936

40-
prettierFormat(markup: string) {
41-
if (this.editorValueType === 'html') {
42-
return prettier.format(markup, {
43-
parser: 'html',
44-
plugins: [parserHtml],
45-
});
37+
this.converter = {
38+
toHtml(value) {
39+
// @ts-expect-error
40+
const result = unified()
41+
// @ts-expect-error
42+
.use(remarkParse)
43+
// @ts-expect-error
44+
.use(remarkRehype)
45+
// @ts-expect-error
46+
.use(rehypeStringify)
47+
.processSync(value)
48+
.toString();
49+
50+
return result;
51+
},
52+
fromHtml(value) {
53+
// @ts-expect-error
54+
const result = unified()
55+
// @ts-expect-error
56+
.use(rehypeParse)
57+
// @ts-expect-error
58+
.use(rehypeRemark)
59+
// @ts-expect-error
60+
.use(remarkStringify)
61+
.processSync(value)
62+
.toString();
63+
64+
return result;
65+
},
4666
}
47-
return markup;
4867
}
4968
}
5069

5170
@NgModule({
5271
imports: [
5372
BrowserModule,
5473
DxHtmlEditorModule,
55-
DxButtonGroupModule,
5674
],
5775
declarations: [AppComponent],
5876
bootstrap: [AppComponent],
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Injectable } from '@angular/core';
2+
3+
const markup = `## ![HtmlEditor](../../../../images/widgets/HtmlEditor.svg) Formatted Text Editor (HTML Editor)
4+
5+
Lists:
6+
7+
1. Use numbers followed by a period for an ordered list.
8+
2. Use a single asterisk for a bullet list.
9+
10+
Formats:
11+
12+
* Enclose a word in single asterisks for *italic*.
13+
* Enclose a word in double asterisks for **bold**.
14+
`;
15+
16+
@Injectable()
17+
export class Service {
18+
getMarkup(): string {
19+
return markup;
20+
}
21+
}

apps/demos/Demos/HtmlEditor/OutputFormats/Angular/index.html renamed to apps/demos/Demos/HtmlEditor/MarkdownSupport/Angular/index.html

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,24 @@
77
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" />
88
<link rel="stylesheet" type="text/css" href="../../../../node_modules/devextreme-dist/css/dx.light.css" />
99

10+
<script type="module">
11+
import { unified } from "https://esm.sh/unified@11?bundle";
12+
import remarkParse from "https://esm.sh/remark-parse@11?bundle";
13+
import remarkRehype from "https://esm.sh/remark-rehype@11?bundle";
14+
import rehypeStringify from "https://esm.sh/rehype-stringify@10?bundle";
15+
import rehypeParse from "https://esm.sh/rehype-parse@9?bundle";
16+
import rehypeRemark from "https://esm.sh/rehype-remark@10?bundle";
17+
import remarkStringify from "https://esm.sh/remark-stringify@11?bundle";
18+
19+
window.unified = unified;
20+
window.remarkParse = remarkParse;
21+
window.remarkRehype = remarkRehype;
22+
window.rehypeStringify = rehypeStringify;
23+
window.rehypeParse = rehypeParse;
24+
window.rehypeRemark = rehypeRemark;
25+
window.remarkStringify = remarkStringify;
26+
</script>
27+
1028
<script src="../../../../node_modules/core-js/client/shim.min.js"></script>
1129
<script src="../../../../node_modules/zone.js/bundles/zone.umd.js"></script>
1230
<script src="../../../../node_modules/reflect-metadata/Reflect.js"></script>
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import React, { useCallback, useState } from 'react';
2+
import HtmlEditor, { Toolbar, Item } from 'devextreme-react/html-editor';
3+
import { markup } from './data.ts';
4+
5+
const headerValues = [false, 1, 2, 3, 4, 5];
6+
const headerOptions = {
7+
inputAttr: {
8+
'aria-label': 'Header',
9+
},
10+
};
11+
const converter = {
12+
toHtml(value) {
13+
// @ts-expect-error
14+
const result = unified()
15+
// @ts-expect-error
16+
.use(remarkParse)
17+
// @ts-expect-error
18+
.use(remarkRehype)
19+
// @ts-expect-error
20+
.use(rehypeStringify)
21+
.processSync(value)
22+
.toString();
23+
24+
return result;
25+
},
26+
fromHtml(value) {
27+
// @ts-expect-error
28+
const result = unified()
29+
// @ts-expect-error
30+
.use(rehypeParse)
31+
// @ts-expect-error
32+
.use(rehypeRemark)
33+
// @ts-expect-error
34+
.use(remarkStringify)
35+
.processSync(value)
36+
.toString();
37+
38+
return result;
39+
},
40+
};
41+
42+
export default function App() {
43+
const [valueContent, setValueContent] = useState(markup);
44+
45+
const valueChanged = useCallback((e: { value?: string; }) => {
46+
setValueContent(e.value);
47+
}, [setValueContent]);
48+
49+
return (
50+
<div className="widget-container">
51+
<HtmlEditor
52+
converter={converter}
53+
height={300}
54+
defaultValue={valueContent}
55+
onValueChanged={valueChanged}
56+
>
57+
<Toolbar>
58+
<Item name="undo" />
59+
<Item name="redo" />
60+
<Item name="separator" />
61+
<Item name="bold" />
62+
<Item name="italic" />
63+
<Item name="separator" />
64+
<Item name="header" acceptedValues={headerValues} options={headerOptions} />
65+
<Item name="separator" />
66+
<Item name="orderedList" />
67+
<Item name="bulletList" />
68+
</Toolbar>
69+
</HtmlEditor>
70+
71+
<div className="options">
72+
<div className="value-title">
73+
Markdown Preview
74+
</div>
75+
<div className="value-content" tabIndex={0}>
76+
{valueContent}
77+
</div>
78+
</div>
79+
</div>
80+
);
81+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export const markup = `## ![HtmlEditor](../../../../images/widgets/HtmlEditor.svg) Formatted Text Editor (HTML Editor)
2+
3+
Lists:
4+
5+
1. Use numbers followed by a period for an ordered list.
6+
2. Use a single asterisk for a bullet list.
7+
8+
Formats:
9+
10+
* Enclose a word in single asterisks for *italic*.
11+
* Enclose a word in double asterisks for **bold**.
12+
`;

apps/demos/Demos/HtmlEditor/OutputFormats/React/index.html renamed to apps/demos/Demos/HtmlEditor/MarkdownSupport/React/index.html

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,24 @@
88
<link rel="stylesheet" type="text/css" href="../../../../node_modules/devextreme-dist/css/dx.light.css" />
99
<link rel="stylesheet" type="text/css" href="styles.css" />
1010

11+
<script type="module">
12+
import { unified } from "https://esm.sh/unified@11?bundle";
13+
import remarkParse from "https://esm.sh/remark-parse@11?bundle";
14+
import remarkRehype from "https://esm.sh/remark-rehype@11?bundle";
15+
import rehypeStringify from "https://esm.sh/rehype-stringify@10?bundle";
16+
import rehypeParse from "https://esm.sh/rehype-parse@9?bundle";
17+
import rehypeRemark from "https://esm.sh/rehype-remark@10?bundle";
18+
import remarkStringify from "https://esm.sh/remark-stringify@11?bundle";
19+
20+
window.unified = unified;
21+
window.remarkParse = remarkParse;
22+
window.remarkRehype = remarkRehype;
23+
window.rehypeStringify = rehypeStringify;
24+
window.rehypeParse = rehypeParse;
25+
window.rehypeRemark = rehypeRemark;
26+
window.remarkStringify = remarkStringify;
27+
</script>
28+
1129
<script src="../../../../node_modules/core-js/client/shim.min.js"></script>
1230
<script src="../../../../node_modules/systemjs/dist/system.js"></script>
1331
<script type="text/javascript" src="config.js"></script>

apps/demos/Demos/HtmlEditor/OutputFormats/React/index.tsx renamed to apps/demos/Demos/HtmlEditor/MarkdownSupport/React/index.tsx

File renamed without changes.

apps/demos/Demos/HtmlEditor/OutputFormats/ReactJs/styles.css renamed to apps/demos/Demos/HtmlEditor/MarkdownSupport/React/styles.css

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
.dx-htmleditor-content img {
22
vertical-align: middle;
33
padding-right: 10px;
4+
margin-bottom: 22px;
5+
}
6+
7+
.value-title {
8+
font-size: var(--dx-font-size-sm);
9+
font-weight: 500;
410
}
511

612
.value-content {
713
margin-top: 20px;
814
overflow: auto;
9-
height: 110px;
10-
width: 100%;
15+
height: 210px;
1116
white-space: pre-wrap;
17+
border: 1px solid var(--dx-color-border);
18+
padding: 16px;
19+
background-color: var(--dx-color-main-bg);
1220
}
1321

1422
.options {

0 commit comments

Comments
 (0)