@web-atoms/web-controls 2.1.9 → 2.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/basic/FormField.d.ts +8 -0
- package/dist/basic/FormField.d.ts.map +1 -0
- package/dist/basic/FormField.js +32 -0
- package/dist/basic/FormField.js.map +1 -0
- package/dist/basic/PopupButton.d.ts +2 -1
- package/dist/basic/PopupButton.d.ts.map +1 -1
- package/dist/basic/PopupButton.js +13 -4
- package/dist/basic/PopupButton.js.map +1 -1
- package/dist/html-editor/HtmlEditor.d.ts +25 -0
- package/dist/html-editor/HtmlEditor.d.ts.map +1 -0
- package/dist/html-editor/HtmlEditor.js +240 -0
- package/dist/html-editor/HtmlEditor.js.map +1 -0
- package/dist/html-editor/commands/AddImage.d.ts +5 -0
- package/dist/html-editor/commands/AddImage.d.ts.map +1 -0
- package/dist/html-editor/commands/AddImage.js +23 -0
- package/dist/html-editor/commands/AddImage.js.map +1 -0
- package/dist/html-editor/commands/AddLink.d.ts +4 -0
- package/dist/html-editor/commands/AddLink.d.ts.map +1 -0
- package/dist/html-editor/commands/AddLink.js +93 -0
- package/dist/html-editor/commands/AddLink.js.map +1 -0
- package/dist/html-editor/commands/Align.d.ts +2 -0
- package/dist/html-editor/commands/Align.d.ts.map +1 -0
- package/dist/html-editor/commands/Align.js +24 -0
- package/dist/html-editor/commands/Align.js.map +1 -0
- package/dist/html-editor/commands/Bold.d.ts +3 -0
- package/dist/html-editor/commands/Bold.d.ts.map +1 -0
- package/dist/html-editor/commands/Bold.js +20 -0
- package/dist/html-editor/commands/Bold.js.map +1 -0
- package/dist/html-editor/commands/ChangeColor.d.ts +2 -0
- package/dist/html-editor/commands/ChangeColor.d.ts.map +1 -0
- package/dist/html-editor/commands/ChangeColor.js +146 -0
- package/dist/html-editor/commands/ChangeColor.js.map +1 -0
- package/dist/html-editor/commands/ChangeFont.d.ts +6 -0
- package/dist/html-editor/commands/ChangeFont.d.ts.map +1 -0
- package/dist/html-editor/commands/ChangeFont.js +72 -0
- package/dist/html-editor/commands/ChangeFont.js.map +1 -0
- package/dist/html-editor/commands/ChangeFontSize.d.ts +3 -0
- package/dist/html-editor/commands/ChangeFontSize.d.ts.map +1 -0
- package/dist/html-editor/commands/ChangeFontSize.js +22 -0
- package/dist/html-editor/commands/ChangeFontSize.js.map +1 -0
- package/dist/html-editor/commands/Command.d.ts +12 -0
- package/dist/html-editor/commands/Command.d.ts.map +1 -0
- package/dist/html-editor/commands/Command.js +43 -0
- package/dist/html-editor/commands/Command.js.map +1 -0
- package/dist/html-editor/commands/CommandButton.d.ts +19 -0
- package/dist/html-editor/commands/CommandButton.d.ts.map +1 -0
- package/dist/html-editor/commands/CommandButton.js +55 -0
- package/dist/html-editor/commands/CommandButton.js.map +1 -0
- package/dist/html-editor/commands/Headings.d.ts +2 -0
- package/dist/html-editor/commands/Headings.d.ts.map +1 -0
- package/dist/html-editor/commands/Headings.js +26 -0
- package/dist/html-editor/commands/Headings.js.map +1 -0
- package/dist/html-editor/commands/HorizontalRule.d.ts +3 -0
- package/dist/html-editor/commands/HorizontalRule.d.ts.map +1 -0
- package/dist/html-editor/commands/HorizontalRule.js +20 -0
- package/dist/html-editor/commands/HorizontalRule.js.map +1 -0
- package/dist/html-editor/commands/IndentLess.d.ts +2 -0
- package/dist/html-editor/commands/IndentLess.d.ts.map +1 -0
- package/dist/html-editor/commands/IndentLess.js +20 -0
- package/dist/html-editor/commands/IndentLess.js.map +1 -0
- package/dist/html-editor/commands/IndentMore.d.ts +2 -0
- package/dist/html-editor/commands/IndentMore.d.ts.map +1 -0
- package/dist/html-editor/commands/IndentMore.js +20 -0
- package/dist/html-editor/commands/IndentMore.js.map +1 -0
- package/dist/html-editor/commands/Italic.d.ts +3 -0
- package/dist/html-editor/commands/Italic.d.ts.map +1 -0
- package/dist/html-editor/commands/Italic.js +20 -0
- package/dist/html-editor/commands/Italic.js.map +1 -0
- package/dist/html-editor/commands/NumberedList.d.ts +2 -0
- package/dist/html-editor/commands/NumberedList.d.ts.map +1 -0
- package/dist/html-editor/commands/NumberedList.js +20 -0
- package/dist/html-editor/commands/NumberedList.js.map +1 -0
- package/dist/html-editor/commands/Quote.d.ts +2 -0
- package/dist/html-editor/commands/Quote.d.ts.map +1 -0
- package/dist/html-editor/commands/Quote.js +20 -0
- package/dist/html-editor/commands/Quote.js.map +1 -0
- package/dist/html-editor/commands/RemoveFormat.d.ts +2 -0
- package/dist/html-editor/commands/RemoveFormat.d.ts.map +1 -0
- package/dist/html-editor/commands/RemoveFormat.js +20 -0
- package/dist/html-editor/commands/RemoveFormat.js.map +1 -0
- package/dist/html-editor/commands/Separator.d.ts +2 -0
- package/dist/html-editor/commands/Separator.d.ts.map +1 -0
- package/dist/html-editor/commands/Separator.js +29 -0
- package/dist/html-editor/commands/Separator.js.map +1 -0
- package/dist/html-editor/commands/Source.d.ts +4 -0
- package/dist/html-editor/commands/Source.d.ts.map +1 -0
- package/dist/html-editor/commands/Source.js +72 -0
- package/dist/html-editor/commands/Source.js.map +1 -0
- package/dist/html-editor/commands/StrikeThrough.d.ts +3 -0
- package/dist/html-editor/commands/StrikeThrough.d.ts.map +1 -0
- package/dist/html-editor/commands/StrikeThrough.js +20 -0
- package/dist/html-editor/commands/StrikeThrough.js.map +1 -0
- package/dist/html-editor/commands/Underline.d.ts +3 -0
- package/dist/html-editor/commands/Underline.d.ts.map +1 -0
- package/dist/html-editor/commands/Underline.js +20 -0
- package/dist/html-editor/commands/Underline.js.map +1 -0
- package/dist/html-editor/commands/Unlink.d.ts +2 -0
- package/dist/html-editor/commands/Unlink.d.ts.map +1 -0
- package/dist/html-editor/commands/Unlink.js +20 -0
- package/dist/html-editor/commands/Unlink.js.map +1 -0
- package/dist/html-editor/commands/UnorderedList.d.ts +2 -0
- package/dist/html-editor/commands/UnorderedList.d.ts.map +1 -0
- package/dist/html-editor/commands/UnorderedList.js +20 -0
- package/dist/html-editor/commands/UnorderedList.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/basic/FormField.tsx +37 -0
- package/src/basic/PopupButton.tsx +15 -4
- package/src/html-editor/HtmlEditor.tsx +242 -0
- package/src/html-editor/commands/AddImage.tsx +13 -0
- package/src/html-editor/commands/AddLink.tsx +90 -0
- package/src/html-editor/commands/Align.tsx +32 -0
- package/src/html-editor/commands/Bold.ts +13 -0
- package/src/html-editor/commands/ChangeColor.tsx +178 -0
- package/src/html-editor/commands/ChangeFont.tsx +75 -0
- package/src/html-editor/commands/ChangeFontSize.tsx +18 -0
- package/src/html-editor/commands/Command.tsx +44 -0
- package/src/html-editor/commands/CommandButton.tsx +68 -0
- package/src/html-editor/commands/Headings.tsx +24 -0
- package/src/html-editor/commands/HorizontalRule.tsx +12 -0
- package/src/html-editor/commands/IndentLess.tsx +13 -0
- package/src/html-editor/commands/IndentMore.tsx +13 -0
- package/src/html-editor/commands/Italic.ts +13 -0
- package/src/html-editor/commands/NumberedList.tsx +13 -0
- package/src/html-editor/commands/Quote.tsx +13 -0
- package/src/html-editor/commands/RemoveFormat.tsx +13 -0
- package/src/html-editor/commands/Separator.tsx +18 -0
- package/src/html-editor/commands/Source.tsx +53 -0
- package/src/html-editor/commands/StrikeThrough.ts +13 -0
- package/src/html-editor/commands/Underline.ts +13 -0
- package/src/html-editor/commands/Unlink.tsx +13 -0
- package/src/html-editor/commands/UnorderedList.tsx +13 -0
|
@@ -3,7 +3,7 @@ import Colors from "@web-atoms/core/dist/core/Colors";
|
|
|
3
3
|
import XNode from "@web-atoms/core/dist/core/XNode";
|
|
4
4
|
import StyleRule from "@web-atoms/core/dist/style/StyleRule";
|
|
5
5
|
import { AtomControl } from "@web-atoms/core/dist/web/controls/AtomControl";
|
|
6
|
-
import PopupService, { IPopup } from "@web-atoms/core/dist/web/services/PopupService";
|
|
6
|
+
import PopupService, { IPopup, IPopupOptions } from "@web-atoms/core/dist/web/services/PopupService";
|
|
7
7
|
import CSS from "@web-atoms/core/dist/web/styles/CSS";
|
|
8
8
|
|
|
9
9
|
const menuCss = CSS(StyleRule()
|
|
@@ -28,6 +28,7 @@ export interface IMenuItem {
|
|
|
28
28
|
export interface IPopupButton {
|
|
29
29
|
icon?: string;
|
|
30
30
|
label?: string;
|
|
31
|
+
showAsDialog?: boolean;
|
|
31
32
|
[key: string]: any;
|
|
32
33
|
}
|
|
33
34
|
|
|
@@ -63,6 +64,7 @@ export default function PopupButton(
|
|
|
63
64
|
{
|
|
64
65
|
icon,
|
|
65
66
|
label,
|
|
67
|
+
showAsDialog,
|
|
66
68
|
... others
|
|
67
69
|
}: IPopupButton,
|
|
68
70
|
... menus: Array<IMenuItem | XNode>) {
|
|
@@ -70,8 +72,8 @@ export default function PopupButton(
|
|
|
70
72
|
let popup: IPopup = null;
|
|
71
73
|
function openPopup(s: AtomControl, e: Event) {
|
|
72
74
|
const button = e.currentTarget as HTMLElement;
|
|
75
|
+
button.classList.add("pressed");
|
|
73
76
|
if (popup) {
|
|
74
|
-
button.classList.remove("pressed");
|
|
75
77
|
popup.dispose();
|
|
76
78
|
popup = null;
|
|
77
79
|
return;
|
|
@@ -83,7 +85,12 @@ export default function PopupButton(
|
|
|
83
85
|
</div>, menu);
|
|
84
86
|
|
|
85
87
|
const ps = (s as any).resolve(PopupService) as PopupService;
|
|
86
|
-
|
|
88
|
+
const options: IPopupOptions = showAsDialog
|
|
89
|
+
? {
|
|
90
|
+
alignment: "centerOfScreen"
|
|
91
|
+
}
|
|
92
|
+
: null;
|
|
93
|
+
popup = ps.show(button, menu, options);
|
|
87
94
|
|
|
88
95
|
const dispose = () => {
|
|
89
96
|
popup?.dispose();
|
|
@@ -92,7 +99,11 @@ export default function PopupButton(
|
|
|
92
99
|
|
|
93
100
|
menu.addEventListener("click", dispose);
|
|
94
101
|
|
|
95
|
-
popup.registerDisposable(() =>
|
|
102
|
+
popup.registerDisposable(() => {
|
|
103
|
+
button.classList.remove("pressed");
|
|
104
|
+
menu.removeEventListener("click", dispose);
|
|
105
|
+
popup = null;
|
|
106
|
+
});
|
|
96
107
|
}
|
|
97
108
|
|
|
98
109
|
if (label) {
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { AtomBinder } from "@web-atoms/core/dist/core/AtomBinder";
|
|
2
|
+
import Bind from "@web-atoms/core/dist/core/Bind";
|
|
3
|
+
import { BindableProperty } from "@web-atoms/core/dist/core/BindableProperty";
|
|
4
|
+
import Colors from "@web-atoms/core/dist/core/Colors";
|
|
5
|
+
import XNode from "@web-atoms/core/dist/core/XNode";
|
|
6
|
+
import StyleRule from "@web-atoms/core/dist/style/StyleRule";
|
|
7
|
+
import { AtomControl } from "@web-atoms/core/dist/web/controls/AtomControl";
|
|
8
|
+
import CSS from "@web-atoms/core/dist/web/styles/CSS";
|
|
9
|
+
import AddImage from "./commands/AddImage";
|
|
10
|
+
import AddLink from "./commands/AddLink";
|
|
11
|
+
import Align from "./commands/Align";
|
|
12
|
+
import Bold from "./commands/Bold";
|
|
13
|
+
import ChangeColor from "./commands/ChangeColor";
|
|
14
|
+
import ChangeFont from "./commands/ChangeFont";
|
|
15
|
+
import ChangeFontSize from "./commands/ChangeFontSize";
|
|
16
|
+
import Headings from "./commands/Headings";
|
|
17
|
+
import HorizontalRule from "./commands/HorizontalRule";
|
|
18
|
+
import IndentLess from "./commands/IndentLess";
|
|
19
|
+
import IndentMore from "./commands/IndentMore";
|
|
20
|
+
import Italic from "./commands/Italic";
|
|
21
|
+
import NumberedList from "./commands/NumberedList";
|
|
22
|
+
import RemoveFormat from "./commands/RemoveFormat";
|
|
23
|
+
import Separator from "./commands/Separator";
|
|
24
|
+
import Source from "./commands/Source";
|
|
25
|
+
import StrikeThrough from "./commands/StrikeThrough";
|
|
26
|
+
import Underline from "./commands/Underline";
|
|
27
|
+
import Unlink from "./commands/Unlink";
|
|
28
|
+
import UnorderedList from "./commands/UnorderedList";
|
|
29
|
+
|
|
30
|
+
const link = document.createElement("link");
|
|
31
|
+
link.href = "https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css";
|
|
32
|
+
link.rel = "stylesheet";
|
|
33
|
+
document.head.appendChild(link);
|
|
34
|
+
|
|
35
|
+
const css = CSS(StyleRule()
|
|
36
|
+
.display("flex")
|
|
37
|
+
.flexDirection("column")
|
|
38
|
+
.minHeight(500)
|
|
39
|
+
.child(StyleRule("iframe")
|
|
40
|
+
.flexBasis("100%")
|
|
41
|
+
)
|
|
42
|
+
.nested(StyleRule(".toolbar")
|
|
43
|
+
.display("flex")
|
|
44
|
+
.child(StyleRule(".command")
|
|
45
|
+
.display("inline-flex")
|
|
46
|
+
.justifyContent("space-evenly" as any)
|
|
47
|
+
.border("none")
|
|
48
|
+
.cursor("pointer")
|
|
49
|
+
.backgroundColor(Colors.transparent)
|
|
50
|
+
.hoverBackgroundColor(Colors.lightGreen)
|
|
51
|
+
.minWidth(28)
|
|
52
|
+
.height(28)
|
|
53
|
+
.and(StyleRule(".pressed")
|
|
54
|
+
.backgroundColor(Colors.lightGray)
|
|
55
|
+
.hoverBackgroundColor(Colors.lightGreen)
|
|
56
|
+
)
|
|
57
|
+
.nested(StyleRule(".ri-bold")
|
|
58
|
+
.fontWeight("bold")
|
|
59
|
+
)
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
export function Toolbar(a: any, ... nodes: XNode[]) {
|
|
65
|
+
return <div class="toolbar">
|
|
66
|
+
{ ... nodes}
|
|
67
|
+
</div>;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export class HtmlEditorControl extends AtomControl {
|
|
71
|
+
|
|
72
|
+
@BindableProperty
|
|
73
|
+
public content: string;
|
|
74
|
+
|
|
75
|
+
@BindableProperty
|
|
76
|
+
public header: any[];
|
|
77
|
+
|
|
78
|
+
@BindableProperty
|
|
79
|
+
public version: number;
|
|
80
|
+
|
|
81
|
+
public editor: HTMLDivElement;
|
|
82
|
+
|
|
83
|
+
public get htmlContent(): string {
|
|
84
|
+
try {
|
|
85
|
+
return this.editor.innerHTML;
|
|
86
|
+
} catch (ex) {
|
|
87
|
+
console.warn(ex);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public set htmlContent(v: string) {
|
|
92
|
+
this.editor.innerHTML = v;
|
|
93
|
+
AtomBinder.refreshValue(this, "htmlContent");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private editorWindow: Window;
|
|
97
|
+
|
|
98
|
+
private editorDocument: Document;
|
|
99
|
+
|
|
100
|
+
public executeCommand(cmd, showUI?: boolean, value?: string): boolean {
|
|
101
|
+
const r = this.editorDocument.execCommand(cmd, showUI, value);
|
|
102
|
+
setTimeout(() => this.version++, 1);
|
|
103
|
+
return r;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
public queryCommandState(cmd: string, ... a: any[]): boolean {
|
|
107
|
+
return this.editorDocument.queryCommandState(cmd);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
public getStyle(name: string, v: any): string {
|
|
111
|
+
try {
|
|
112
|
+
const node = this.editorWindow.getSelection().getRangeAt(0);
|
|
113
|
+
const e = node.startContainer.parentElement as HTMLElement;
|
|
114
|
+
return this.editorWindow.getComputedStyle(e)[name];
|
|
115
|
+
} catch (ex) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
protected preCreate() {
|
|
121
|
+
this.version = 1;
|
|
122
|
+
this.runAfterInit(() => {
|
|
123
|
+
this.setup();
|
|
124
|
+
});
|
|
125
|
+
this.element.classList.add(css);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
protected onPasteEvent(e: ClipboardEvent) {
|
|
129
|
+
// tslint:disable-next-line: no-console
|
|
130
|
+
if (!e.clipboardData.types.find((x) => x === "text/html")) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const d = e.clipboardData.getData("text/plain");
|
|
135
|
+
if (d) {
|
|
136
|
+
// we need to sanitize this one...
|
|
137
|
+
const s = window.getSelection();
|
|
138
|
+
const r = s.getRangeAt(0);
|
|
139
|
+
const p = document.createElement("p");
|
|
140
|
+
const span = document.createElement("span");
|
|
141
|
+
span.textContent = d;
|
|
142
|
+
p.appendChild(span);
|
|
143
|
+
r.insertNode(p);
|
|
144
|
+
r.setStartAfter(p);
|
|
145
|
+
}
|
|
146
|
+
e.preventDefault();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
protected onInputEvent(e: InputEvent) {
|
|
150
|
+
// tslint:disable-next-line: no-console
|
|
151
|
+
console.log(e);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
protected setup() {
|
|
155
|
+
const frame = this.element.getElementsByTagName("iframe")[0] as HTMLIFrameElement;
|
|
156
|
+
const doc = frame.contentWindow.document;
|
|
157
|
+
doc.open();
|
|
158
|
+
doc.writeln(`<div id="editor"><p> </p></div>`);
|
|
159
|
+
doc.close();
|
|
160
|
+
const style = doc.createElement("style");
|
|
161
|
+
style.textContent = `body {
|
|
162
|
+
font-family: arial,sans-serif
|
|
163
|
+
}
|
|
164
|
+
#editor {
|
|
165
|
+
min-height: 500px;
|
|
166
|
+
}
|
|
167
|
+
`;
|
|
168
|
+
doc.head.appendChild(style);
|
|
169
|
+
this.editor = doc.getElementById("editor") as HTMLDivElement;
|
|
170
|
+
this.editor.contentEditable = "true";
|
|
171
|
+
doc.execCommand("styleWithCSS");
|
|
172
|
+
const updateVersion = () => setTimeout(() => {
|
|
173
|
+
this.version++;
|
|
174
|
+
AtomBinder.refreshValue(this, "htmlContent");
|
|
175
|
+
}, 1);
|
|
176
|
+
this.editor.addEventListener("click", updateVersion);
|
|
177
|
+
this.editor.addEventListener("keydown", updateVersion);
|
|
178
|
+
this.editor.addEventListener("keypress", updateVersion);
|
|
179
|
+
this.editor.addEventListener("input", updateVersion);
|
|
180
|
+
this.editorWindow = frame.contentWindow;
|
|
181
|
+
this.editorDocument = doc;
|
|
182
|
+
|
|
183
|
+
this.registerDisposable({
|
|
184
|
+
dispose: () => {
|
|
185
|
+
this.editor.removeEventListener("click", updateVersion);
|
|
186
|
+
this.editor.removeEventListener("keydown", updateVersion);
|
|
187
|
+
this.editor.removeEventListener("keypress", updateVersion);
|
|
188
|
+
this.editor.removeEventListener("input", updateVersion);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export interface IHtmlEditor {
|
|
195
|
+
insertImage?: (s: HtmlEditorControl, e: Event) => Promise<string> | string;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export default function HtmlEditor(
|
|
199
|
+
{
|
|
200
|
+
insertImage,
|
|
201
|
+
... attributes
|
|
202
|
+
}: any,
|
|
203
|
+
... nodes: XNode[]) {
|
|
204
|
+
|
|
205
|
+
if (nodes.length === 0) {
|
|
206
|
+
return <HtmlEditorControl { ... attributes}>
|
|
207
|
+
<Toolbar>
|
|
208
|
+
<Bold/>
|
|
209
|
+
<Italic/>
|
|
210
|
+
<Underline/>
|
|
211
|
+
<StrikeThrough/>
|
|
212
|
+
<Align/>
|
|
213
|
+
<Separator/>
|
|
214
|
+
<Headings/>
|
|
215
|
+
<ChangeColor/>
|
|
216
|
+
<HorizontalRule/>
|
|
217
|
+
<Separator/>
|
|
218
|
+
<ChangeFont/>
|
|
219
|
+
<ChangeFontSize/>
|
|
220
|
+
<Separator/>
|
|
221
|
+
<NumberedList/>
|
|
222
|
+
<UnorderedList/>
|
|
223
|
+
<IndentLess/>
|
|
224
|
+
<IndentMore/>
|
|
225
|
+
<Separator/>
|
|
226
|
+
<AddImage eventInsertHtml={insertImage}/>
|
|
227
|
+
<Separator/>
|
|
228
|
+
<AddLink/>
|
|
229
|
+
<Unlink/>
|
|
230
|
+
<RemoveFormat/>
|
|
231
|
+
<Separator/>
|
|
232
|
+
<Source/>
|
|
233
|
+
</Toolbar>
|
|
234
|
+
<iframe class="editor-frame"/>
|
|
235
|
+
</HtmlEditorControl>;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return <HtmlEditorControl { ... attributes}>
|
|
239
|
+
{ ... nodes}
|
|
240
|
+
<iframe class="editor-frame"/>
|
|
241
|
+
</HtmlEditorControl>;
|
|
242
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import CommandButton, { notSet } from "./CommandButton";
|
|
2
|
+
|
|
3
|
+
export default function AddImage({
|
|
4
|
+
eventInsertHtml = notSet("AddImage"),
|
|
5
|
+
insertCommand = "insertHTML"
|
|
6
|
+
}) {
|
|
7
|
+
return CommandButton({
|
|
8
|
+
icon: "ri-image-add-fill",
|
|
9
|
+
insertCommand,
|
|
10
|
+
title: "Insert Image",
|
|
11
|
+
eventInsertHtml
|
|
12
|
+
});
|
|
13
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import Bind from "@web-atoms/core/dist/core/Bind";
|
|
2
|
+
import { BindableProperty } from "@web-atoms/core/dist/core/BindableProperty";
|
|
3
|
+
import { CancelToken } from "@web-atoms/core/dist/core/types";
|
|
4
|
+
import XNode from "@web-atoms/core/dist/core/XNode";
|
|
5
|
+
import StyleRule from "@web-atoms/core/dist/style/StyleRule";
|
|
6
|
+
import { AtomToggleButtonBar } from "@web-atoms/core/dist/web/controls/AtomToggleButtonBar";
|
|
7
|
+
import PopupService, { PopupWindow } from "@web-atoms/core/dist/web/services/PopupService";
|
|
8
|
+
import CSS from "@web-atoms/core/dist/web/styles/CSS";
|
|
9
|
+
import FormField from "../../basic/FormField";
|
|
10
|
+
import type { HtmlEditorControl } from "../HtmlEditor";
|
|
11
|
+
import CommandButton, { notSet } from "./CommandButton";
|
|
12
|
+
|
|
13
|
+
const linkTypes = [
|
|
14
|
+
{
|
|
15
|
+
label: "Web Page",
|
|
16
|
+
value: "web-page"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
label: "Email",
|
|
20
|
+
value: "email"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
label: "Anchor",
|
|
24
|
+
value: "anchor"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
label: "Phone",
|
|
28
|
+
value: "phone"
|
|
29
|
+
}
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
const linkDialogCss = CSS(StyleRule()
|
|
33
|
+
.display("flex")
|
|
34
|
+
.flexDirection("column")
|
|
35
|
+
.gap(5)
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
class LinkDialog extends PopupWindow {
|
|
39
|
+
|
|
40
|
+
@BindableProperty
|
|
41
|
+
public link: string;
|
|
42
|
+
|
|
43
|
+
@BindableProperty
|
|
44
|
+
public type: string;
|
|
45
|
+
|
|
46
|
+
protected create(): void {
|
|
47
|
+
this.type = "web-page";
|
|
48
|
+
this.title = "Create Link";
|
|
49
|
+
this.render(<div class={linkDialogCss}>
|
|
50
|
+
<FormField label="Type">
|
|
51
|
+
<AtomToggleButtonBar
|
|
52
|
+
items={linkTypes}
|
|
53
|
+
value={Bind.twoWays(() => this.type)}/>
|
|
54
|
+
</FormField>
|
|
55
|
+
<FormField label="Link" required={true}>
|
|
56
|
+
<input
|
|
57
|
+
placeholder="https://..."
|
|
58
|
+
value={Bind.twoWaysImmediate(() => this.link)}/>
|
|
59
|
+
</FormField>
|
|
60
|
+
<div class="command-bar">
|
|
61
|
+
<button
|
|
62
|
+
text="Add"
|
|
63
|
+
eventClick={Bind.event(() => this.viewModel.close(this.toLink(this.link)))} />
|
|
64
|
+
</div>
|
|
65
|
+
</div>);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private toLink(link: string): string {
|
|
69
|
+
switch (this.type) {
|
|
70
|
+
case "web-page":
|
|
71
|
+
return /^(http|https)\:\/\//.test(link) ? link : "";
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function showDialog(s: HtmlEditorControl, e: Event): Promise<string> {
|
|
77
|
+
const popupService = s.app.resolve(PopupService);
|
|
78
|
+
return popupService.showWindow(s.element, LinkDialog);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export default function AddLink({
|
|
82
|
+
insertCommand = "createLink"
|
|
83
|
+
}) {
|
|
84
|
+
return CommandButton({
|
|
85
|
+
icon: "ri-link-m",
|
|
86
|
+
insertCommand,
|
|
87
|
+
eventInsertHtml: showDialog,
|
|
88
|
+
title: "Create Hyper Link"
|
|
89
|
+
});
|
|
90
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import Bind from "@web-atoms/core/dist/core/Bind";
|
|
2
|
+
import XNode from "@web-atoms/core/dist/core/XNode";
|
|
3
|
+
import PopupButton, { MenuItem } from "../../basic/PopupButton";
|
|
4
|
+
import type { HtmlEditorControl } from "../HtmlEditor";
|
|
5
|
+
|
|
6
|
+
export default function Align() {
|
|
7
|
+
return <PopupButton
|
|
8
|
+
class="command"
|
|
9
|
+
icon="ri-align-left"
|
|
10
|
+
title="Change Alignment">
|
|
11
|
+
<MenuItem
|
|
12
|
+
icon="ri-align-left"
|
|
13
|
+
title="Align Left"
|
|
14
|
+
eventClick={Bind.event((e: HtmlEditorControl) =>
|
|
15
|
+
e.executeCommand("justifyLeft"))}/>
|
|
16
|
+
<MenuItem
|
|
17
|
+
icon="ri-align-center"
|
|
18
|
+
title="Align Center"
|
|
19
|
+
eventClick={Bind.event((e: HtmlEditorControl) =>
|
|
20
|
+
e.executeCommand("justifyCenter"))}/>
|
|
21
|
+
<MenuItem
|
|
22
|
+
icon="ri-align-right"
|
|
23
|
+
title="Align Right"
|
|
24
|
+
eventClick={Bind.event((e: HtmlEditorControl) =>
|
|
25
|
+
e.executeCommand("justifyRight"))}/>
|
|
26
|
+
<MenuItem
|
|
27
|
+
icon="ri-align-justify"
|
|
28
|
+
title="Justify"
|
|
29
|
+
eventClick={Bind.event((e: HtmlEditorControl) =>
|
|
30
|
+
e.executeCommand("justifyFull"))}/>
|
|
31
|
+
</PopupButton>;
|
|
32
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import Command, { ICommand } from "./Command";
|
|
2
|
+
|
|
3
|
+
export default function Bold(cmd: ICommand) {
|
|
4
|
+
return Command({
|
|
5
|
+
icon: "ri-bold",
|
|
6
|
+
queryState: "bold",
|
|
7
|
+
title: "Bold",
|
|
8
|
+
... cmd,
|
|
9
|
+
command(editor) {
|
|
10
|
+
editor.executeCommand("bold");
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import Bind from "@web-atoms/core/dist/core/Bind";
|
|
2
|
+
import XNode from "@web-atoms/core/dist/core/XNode";
|
|
3
|
+
import StyleRule from "@web-atoms/core/dist/style/StyleRule";
|
|
4
|
+
import CSS from "@web-atoms/core/dist/web/styles/CSS";
|
|
5
|
+
import PopupButton from "../../basic/PopupButton";
|
|
6
|
+
import type { HtmlEditorControl } from "../HtmlEditor";
|
|
7
|
+
|
|
8
|
+
const gray = [
|
|
9
|
+
"rgb(0,0,0)",
|
|
10
|
+
"rgb(68,68,68)",
|
|
11
|
+
"rgb(102,102,102)",
|
|
12
|
+
"rgb(153,153,153)",
|
|
13
|
+
"rgb(204,204,204)",
|
|
14
|
+
"rgb(238,238,238)",
|
|
15
|
+
"rgb(243,243,243)",
|
|
16
|
+
"rgb(255,255,255)"
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
const primary = [
|
|
20
|
+
"rgb(255,0,0)",
|
|
21
|
+
"rgb(255,153,0)",
|
|
22
|
+
"rgb(255,255,0)",
|
|
23
|
+
"rgb(0,255,0)",
|
|
24
|
+
"rgb(0,255,255)",
|
|
25
|
+
"rgb(0,0,255)",
|
|
26
|
+
"rgb(153,0,255)",
|
|
27
|
+
"rgb(255,0,255)"
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
const all = [
|
|
31
|
+
[
|
|
32
|
+
"rgb(244,204,204)",
|
|
33
|
+
"rgb(252,229,205)",
|
|
34
|
+
"rgb(255,242,204)",
|
|
35
|
+
"rgb(217,234,211)",
|
|
36
|
+
"rgb(208,224,227)",
|
|
37
|
+
"rgb(207,226,243)",
|
|
38
|
+
"rgb(217,210,233)",
|
|
39
|
+
"rgb(234,209,220)"
|
|
40
|
+
],
|
|
41
|
+
[
|
|
42
|
+
"rgb(234,153,153)",
|
|
43
|
+
"rgb(249,203,156)",
|
|
44
|
+
"rgb(255,229,153)",
|
|
45
|
+
"rgb(182,215,168)",
|
|
46
|
+
"rgb(162,196,201)",
|
|
47
|
+
"rgb(159,197,232)",
|
|
48
|
+
"rgb(180,167,214)",
|
|
49
|
+
"rgb(213,166,189)"
|
|
50
|
+
],
|
|
51
|
+
[
|
|
52
|
+
"rgb(224,102,102)",
|
|
53
|
+
"rgb(246,178,107)",
|
|
54
|
+
"rgb(255,217,102)",
|
|
55
|
+
"rgb(147,196,125)",
|
|
56
|
+
"rgb(118,165,175)",
|
|
57
|
+
"rgb(111,168,220)",
|
|
58
|
+
"rgb(142,124,195)",
|
|
59
|
+
"rgb(194,123,160)"
|
|
60
|
+
],
|
|
61
|
+
[
|
|
62
|
+
"rgb(204,0,0)",
|
|
63
|
+
"rgb(230,145,56)",
|
|
64
|
+
"rgb(241,194,50)",
|
|
65
|
+
"rgb(106,168,79)",
|
|
66
|
+
"rgb(69,129,142)",
|
|
67
|
+
"rgb(61,133,198)",
|
|
68
|
+
"rgb(103,78,167)",
|
|
69
|
+
"rgb(166,77,121)"
|
|
70
|
+
],
|
|
71
|
+
[
|
|
72
|
+
"rgb(153,0,0)",
|
|
73
|
+
"rgb(180,95,6)",
|
|
74
|
+
"rgb(191,144,0)",
|
|
75
|
+
"rgb(56,118,29)",
|
|
76
|
+
"rgb(19,79,92)",
|
|
77
|
+
"rgb(11,83,148)",
|
|
78
|
+
"rgb(53,28,117)",
|
|
79
|
+
"rgb(116,27,71)"
|
|
80
|
+
],
|
|
81
|
+
[
|
|
82
|
+
"rgb(102,0,0)",
|
|
83
|
+
"rgb(120,63,4)",
|
|
84
|
+
"rgb(127,96,0)",
|
|
85
|
+
"rgb(39,78,19)",
|
|
86
|
+
"rgb(12,52,61)",
|
|
87
|
+
"rgb(7,55,99)",
|
|
88
|
+
"rgb(32,18,77)",
|
|
89
|
+
"rgb(76,17,48)"
|
|
90
|
+
]
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
const colorSelectorCss = CSS(StyleRule("color-selector")
|
|
94
|
+
.width(400)
|
|
95
|
+
.display("flex")
|
|
96
|
+
.justifyContent("space-evenly" as any)
|
|
97
|
+
.child(StyleRule("table")
|
|
98
|
+
.display("inline-table")
|
|
99
|
+
)
|
|
100
|
+
.nested(StyleRule(".color-button")
|
|
101
|
+
.display("inline-block")
|
|
102
|
+
.width(20)
|
|
103
|
+
.height(20)
|
|
104
|
+
.borderWidth(1)
|
|
105
|
+
.margin(1)
|
|
106
|
+
.cursor("pointer")
|
|
107
|
+
.borderStyle("solid")
|
|
108
|
+
.borderColor("transparent")
|
|
109
|
+
.hover(StyleRule()
|
|
110
|
+
.borderColor("black")
|
|
111
|
+
)
|
|
112
|
+
)
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
function TextColor(color: string) {
|
|
116
|
+
return <div
|
|
117
|
+
class="color-button"
|
|
118
|
+
eventClick={Bind.event((e: HtmlEditorControl) => e.executeCommand("foreColor", false, color))}
|
|
119
|
+
styleBackgroundColor={color.toLowerCase()} title={color}></div>;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function BackgroundColor(color: string) {
|
|
123
|
+
return <div
|
|
124
|
+
class="color-button"
|
|
125
|
+
eventClick={Bind.event((e: HtmlEditorControl) => e.executeCommand("hiliteColor", false, color))}
|
|
126
|
+
styleBackgroundColor={color.toLowerCase()} title={color}></div>;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export default function ChangeColor() {
|
|
130
|
+
return <PopupButton title="Change Color" class="command" icon="ri-font-color">
|
|
131
|
+
<div class={colorSelectorCss}>
|
|
132
|
+
<table>
|
|
133
|
+
<thead>
|
|
134
|
+
<tr>
|
|
135
|
+
<th colSpan={8}>Text Color</th>
|
|
136
|
+
</tr>
|
|
137
|
+
</thead>
|
|
138
|
+
<thead>
|
|
139
|
+
<tr>
|
|
140
|
+
{ ... gray.map(TextColor)}
|
|
141
|
+
</tr>
|
|
142
|
+
</thead>
|
|
143
|
+
<thead>
|
|
144
|
+
<tr>
|
|
145
|
+
{ ... primary.map(TextColor)}
|
|
146
|
+
</tr>
|
|
147
|
+
</thead>
|
|
148
|
+
<tbody>
|
|
149
|
+
{ ... all.map((row) => <tr>
|
|
150
|
+
{ ... row.map(TextColor)}
|
|
151
|
+
</tr>)}
|
|
152
|
+
</tbody>
|
|
153
|
+
</table>
|
|
154
|
+
<table class="background-color">
|
|
155
|
+
<thead>
|
|
156
|
+
<tr>
|
|
157
|
+
<th colSpan={8}>Background Color</th>
|
|
158
|
+
</tr>
|
|
159
|
+
</thead>
|
|
160
|
+
<thead>
|
|
161
|
+
<tr>
|
|
162
|
+
{ ... gray.map(BackgroundColor)}
|
|
163
|
+
</tr>
|
|
164
|
+
</thead>
|
|
165
|
+
<thead>
|
|
166
|
+
<tr>
|
|
167
|
+
{ ... primary.map(BackgroundColor)}
|
|
168
|
+
</tr>
|
|
169
|
+
</thead>
|
|
170
|
+
<tbody>
|
|
171
|
+
{ ... all.map((row) => <tr>
|
|
172
|
+
{ ... row.map(BackgroundColor)}
|
|
173
|
+
</tr>)}
|
|
174
|
+
</tbody>
|
|
175
|
+
</table>
|
|
176
|
+
</div>
|
|
177
|
+
</PopupButton>;
|
|
178
|
+
}
|