@ember-eui/core 1.2.3 → 1.3.3

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.
Files changed (78) hide show
  1. package/CHANGELOG.md +25 -4
  2. package/README.md +1 -1
  3. package/addon/components/common.ts +13 -0
  4. package/addon/components/eui-button/index.hbs +2 -0
  5. package/addon/components/eui-button-content/index.hbs +1 -0
  6. package/addon/components/eui-button-empty/index.hbs +2 -0
  7. package/addon/components/eui-button-icon/index.hbs +2 -0
  8. package/addon/components/eui-code/index.hbs +9 -0
  9. package/addon/components/eui-code-block/index.d.ts +2 -0
  10. package/addon/components/eui-code-block/index.hbs +10 -0
  11. package/addon/components/eui-code-block-impl/code-block-controls/index.hbs +33 -0
  12. package/addon/components/eui-code-block-impl/index.hbs +111 -0
  13. package/addon/components/eui-code-block-impl/index.ts +121 -0
  14. package/addon/components/eui-combo-box/index.hbs +3 -2
  15. package/addon/components/eui-combo-box/trigger/index.hbs +118 -112
  16. package/addon/components/eui-copy/index.hbs +8 -0
  17. package/addon/components/eui-copy/index.ts +37 -0
  18. package/addon/components/eui-icon/index.hbs +37 -32
  19. package/addon/components/eui-inner-text/index.hbs +1 -0
  20. package/addon/components/eui-inner-text/index.ts +61 -0
  21. package/addon/components/eui-markdown-editor/index.hbs +63 -0
  22. package/addon/components/eui-markdown-editor/index.ts +221 -0
  23. package/addon/components/eui-markdown-editor-drop-zone/index.hbs +21 -0
  24. package/addon/components/eui-markdown-editor-drop-zone/index.ts +5 -0
  25. package/addon/components/eui-markdown-editor-footer/index.hbs +108 -0
  26. package/addon/components/eui-markdown-editor-footer/index.ts +20 -0
  27. package/addon/components/eui-markdown-editor-text-area/index.hbs +8 -0
  28. package/addon/components/eui-markdown-editor-toolbar/index.hbs +86 -0
  29. package/addon/components/eui-markdown-editor-toolbar/index.ts +97 -0
  30. package/addon/components/eui-markdown-format/index.hbs +13 -0
  31. package/addon/components/eui-markdown-format/index.ts +45 -0
  32. package/addon/components/eui-markdown-format/markdown-checkbox/index.hbs +8 -0
  33. package/addon/components/eui-markdown-format/markdown-checkbox/index.ts +28 -0
  34. package/addon/components/eui-markdown-format/markdown-code/index.hbs +3 -0
  35. package/addon/components/eui-markdown-format/markdown-code-block/index.hbs +7 -0
  36. package/addon/components/eui-markdown-format/markdown-tooltip/index.hbs +8 -0
  37. package/addon/components/markdown-checkmark-icon/index.hbs +0 -0
  38. package/addon/modifiers/get-cursor-node.ts +54 -0
  39. package/addon/modifiers/resize-observer.ts +6 -2
  40. package/addon/utils/copy-to-clipboard.ts +70 -0
  41. package/addon/utils/css-mappings/eui-code-block-impl.ts +24 -0
  42. package/addon/utils/css-mappings/index.ts +2 -0
  43. package/addon/utils/markdown/markdown-actions.ts +616 -0
  44. package/addon/utils/markdown/markdown-modes.ts +23 -0
  45. package/addon/utils/markdown/markdown-types.ts +140 -0
  46. package/addon/utils/markdown/markdown-unified-plugins.d.ts +27 -0
  47. package/addon/utils/markdown/plugins/markdown-add-components.ts +63 -0
  48. package/addon/utils/markdown/plugins/markdown-checkbox.ts +80 -0
  49. package/addon/utils/markdown/plugins/markdown-default-plugins.ts +100 -0
  50. package/addon/utils/markdown/plugins/markdown-tooltip.ts +113 -0
  51. package/addon/utils/markdown/plugins/to-dom.ts +93 -0
  52. package/app/components/eui-code/index.js +1 -0
  53. package/app/components/eui-code-block/index.js +1 -0
  54. package/app/components/eui-code-block-impl/code-block-controls/index.js +1 -0
  55. package/app/components/eui-code-block-impl/index.js +1 -0
  56. package/app/components/eui-copy/index.js +1 -0
  57. package/app/components/eui-inner-text/index.js +1 -0
  58. package/app/components/eui-markdown-editor/index.js +1 -0
  59. package/app/components/eui-markdown-editor-drop-zone/index.js +1 -0
  60. package/app/components/eui-markdown-editor-footer/index.js +1 -0
  61. package/app/components/eui-markdown-editor-text-area/index.js +1 -0
  62. package/app/components/eui-markdown-editor-toolbar/index.js +1 -0
  63. package/app/components/eui-markdown-format/index.js +1 -0
  64. package/app/components/eui-markdown-format/markdown-checkbox/index.js +1 -0
  65. package/app/components/eui-markdown-format/markdown-code/index.js +1 -0
  66. package/app/components/eui-markdown-format/markdown-code-block/index.js +1 -0
  67. package/app/components/eui-markdown-format/markdown-tooltip/index.js +1 -0
  68. package/app/modifiers/get-cursor-node.js +1 -0
  69. package/app/styles/ember-eui.scss +13 -0
  70. package/docs/editors/code/code-block-demo/demo1.md +62 -0
  71. package/docs/editors/code/code-block.md +1 -0
  72. package/docs/editors/code/inline-demo/demo1.md +49 -0
  73. package/docs/editors/code/inline.md +1 -0
  74. package/docs/editors/markdown-editor/base-editor-demo/demo1.md +86 -0
  75. package/docs/editors/markdown-editor/base-editor.md +1 -0
  76. package/package.json +32 -6
  77. package/public/markdown-checkmark.svg +3 -0
  78. package/public/markdown-logo.svg +3 -0
@@ -0,0 +1,8 @@
1
+ <EuiToolTip @onMouseOut={{this.resetTooltipText}} ...attributes>
2
+ <:anchor>
3
+ {{yield this.copy}}
4
+ </:anchor>
5
+ <:content>
6
+ {{this.tooltipText}}
7
+ </:content>
8
+ </EuiToolTip>
@@ -0,0 +1,37 @@
1
+ import Component from '@glimmer/component';
2
+ import { action } from '@ember/object';
3
+ import { tracked } from '@glimmer/tracking';
4
+ import { copyToClipboard } from '../../utils/copy-to-clipboard';
5
+
6
+ type EuiCopyArgs = {
7
+ /**
8
+ * Text that will be copied to clipboard when copy function is executed.
9
+ */
10
+ textToCopy: string;
11
+ /**
12
+ * Tooltip message displayed before copy function is called.
13
+ */
14
+ beforeMessage?: string;
15
+ /**
16
+ * Tooltip message displayed after copy function is called that lets the user know that
17
+ * 'textToCopy' has been copied to the clipboard.
18
+ */
19
+ afterMessage?: string;
20
+ };
21
+
22
+ export default class EuiCopyComponent extends Component<EuiCopyArgs> {
23
+ @tracked tooltipText = this.args.beforeMessage;
24
+
25
+ @action
26
+ copy(): void {
27
+ const isCopied = copyToClipboard(this.args.textToCopy);
28
+ if (isCopied) {
29
+ this.tooltipText = this.args.afterMessage;
30
+ }
31
+ }
32
+
33
+ @action
34
+ resetTooltipText(): void {
35
+ this.tooltipText = this.args.beforeMessage;
36
+ }
37
+ }
@@ -1,34 +1,39 @@
1
- {{#if this.useImage}}
2
- <img
3
- src={{this.icon}}
4
- class={{class-names
5
- this.optionalColorClass
6
- (if this.isAppIcon "euiIcon--app")
7
- componentName="EuiIcon"
8
- size=this.size
9
- }}
10
- alt={{if @title @title}}
11
- tabIndex={{@tabIndex}}
12
- ...attributes
13
- />
1
+ {{#if this.icon.inner}}
2
+ {{! has the shape of a curried component }}
3
+ {{component this.icon}}
14
4
  {{else}}
15
- <Svg
16
- @name={{this.icon}}
17
- @loadingSvg={{this.emptyIcon}}
18
- class={{class-names
19
- this.optionalColorClass
20
- (if this.isAppIcon "euiIcon--app")
21
- componentName="EuiIcon"
22
- size=this.size
23
- }}
24
- style={{this.optionalCustomStyles}}
25
- tabIndex={{this.tabIndex}}
26
- role="image"
27
- aria-hidden={{if this.isAriaHidden true}}
28
- aria-label={{if @aria-label @aria-label this.titleId}}
29
- aria-labelledby={{if @aria-labelledby @aria-labelledby this.titleId}}
30
- @title={{@title}}
31
- @onIconLoad={{@onIconLoad}}
32
- ...attributes
33
- />
5
+ {{#if this.useImage}}
6
+ <img
7
+ src={{this.icon}}
8
+ class={{class-names
9
+ this.optionalColorClass
10
+ (if this.isAppIcon "euiIcon--app")
11
+ componentName="EuiIcon"
12
+ size=this.size
13
+ }}
14
+ alt={{if @title @title}}
15
+ tabIndex={{@tabIndex}}
16
+ ...attributes
17
+ />
18
+ {{else}}
19
+ <Svg
20
+ @name={{this.icon}}
21
+ @loadingSvg={{this.emptyIcon}}
22
+ class={{class-names
23
+ this.optionalColorClass
24
+ (if this.isAppIcon "euiIcon--app")
25
+ componentName="EuiIcon"
26
+ size=this.size
27
+ }}
28
+ style={{this.optionalCustomStyles}}
29
+ tabIndex={{this.tabIndex}}
30
+ role="image"
31
+ aria-hidden={{if this.isAriaHidden true}}
32
+ aria-label={{if @aria-label @aria-label this.titleId}}
33
+ aria-labelledby={{if @aria-labelledby @aria-labelledby this.titleId}}
34
+ @title={{@title}}
35
+ @onIconLoad={{@onIconLoad}}
36
+ ...attributes
37
+ />
38
+ {{/if}}
34
39
  {{/if}}
@@ -0,0 +1 @@
1
+ {{yield this.setRef this.innerText}}
@@ -0,0 +1,61 @@
1
+ import GlimmerComponent from '@glimmer/component';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { action } from '@ember/object';
4
+
5
+ type InnerTextArgs = {
6
+ fallback?: string;
7
+ };
8
+
9
+ export default class EuiImage extends GlimmerComponent<InnerTextArgs> {
10
+ @tracked ref: HTMLElement | null = null;
11
+ @tracked innerText = '';
12
+ observer: MutationObserver | null = null;
13
+
14
+ get innerTextFallback() {
15
+ return this.args.fallback ?? '';
16
+ }
17
+
18
+ setupObserver() {
19
+ this.observer?.disconnect();
20
+ this.observer = new MutationObserver((mutationsList) => {
21
+ if (mutationsList.length) this.updateInnerText(this.ref);
22
+ });
23
+ if (this.ref) {
24
+ this.updateInnerText(this.ref);
25
+ this.observer.observe(this.ref, {
26
+ characterData: true,
27
+ subtree: true,
28
+ childList: true
29
+ });
30
+ }
31
+ }
32
+
33
+ updateInnerText(node: HTMLElement | null) {
34
+ if (!node) return;
35
+ this.setInnerText(
36
+ // Check for `innerText` implementation rather than a simple OR check
37
+ // because in real cases the result of `innerText` could correctly be `null`
38
+ // while the result of `textContent` could correctly be non-`null` due to
39
+ // differing reliance on browser layout calculations.
40
+ // We prefer the result of `innerText`, if available.
41
+ 'innerText' in node
42
+ ? node.innerText
43
+ : (node as HTMLElement).textContent || this.innerTextFallback
44
+ );
45
+ }
46
+
47
+ setInnerText(text: string) {
48
+ this.innerText = text;
49
+ }
50
+
51
+ @action
52
+ setRef(ref: HTMLElement): void {
53
+ this.ref = ref;
54
+ this.setupObserver();
55
+ }
56
+
57
+ willDestroy(): void {
58
+ super.willDestroy();
59
+ this.observer?.disconnect();
60
+ }
61
+ }
@@ -0,0 +1,63 @@
1
+ <div
2
+ class={{class-names
3
+ "euiMarkdownEditor"
4
+ (if (eq this.height "full") "euiMarkdownEditor--fullHeight")
5
+ (if this.isPreviewing "euiMarkdownEditor--isPreviewing")
6
+ }}
7
+ {{did-update
8
+ this.updateCurrentHeight
9
+ this.currentHeight
10
+ this.isPreviewing
11
+ this.height
12
+ this.autoExpandPreview
13
+ }}
14
+ >
15
+ <EuiMarkdownEditorToolbar
16
+ @selectedNode={{this.selectedNode}}
17
+ @markdownActions={{this.markdownActions}}
18
+ @onClickPreview={{this.setViewMode}}
19
+ @viewMode={{this.viewMode}}
20
+ @uiPlugins={{this.toolbarPlugins}}
21
+ {{did-insert this.setEditorToolbarRef}}
22
+ />
23
+ {{#if this.isPreviewing}}
24
+ <div
25
+ class="euiMarkdownEditorPreview"
26
+ {{did-insert (set this "previewRef")}}
27
+ {{style (hash height=this.previewHeight)}}
28
+ >
29
+ <EuiMarkdownFormat
30
+ @parsingPluginList={{this.parsingPluginList}}
31
+ @processingPluginList={{this.processingPluginList}}
32
+ @value={{@value}}
33
+ @replaceNode={{this.replaceNode}}
34
+ />
35
+ </div>
36
+ {{/if}}
37
+
38
+ <div
39
+ class="euiMarkdownEditor__toggleContainer"
40
+ {{style height=this.editorToggleContainerHeight}}
41
+ >
42
+ <EuiMarkdownEditorDropZone
43
+ @uiPlugins={{this.toolbarPlugins}}
44
+ {{resize-observer onResize=this.onResize}}
45
+ >
46
+ <EuiMarkdownEditorTextArea
47
+ {{get-cursor-node (get this.parsed "0") this.setSelectedNode}}
48
+ {{did-update this.onParse this.parsed}}
49
+ {{did-insert this.setTextAreaRef}}
50
+ disabled={{@disabled}}
51
+ id={{this.editorId}}
52
+ @height={{this.textAreaHeight}}
53
+ @maxHeight={{this.textAreaMaxHeight}}
54
+ value={{@value}}
55
+ aria-label={{@ariaLabel}}
56
+ aria-labelledby={{@ariaLabelledBy}}
57
+ aria-describedby={{@ariaDescribedBy}}
58
+ {{on "input" (pick "target.value" @onChange)}}
59
+ ...attributes
60
+ />
61
+ </EuiMarkdownEditorDropZone>
62
+ </div>
63
+ </div>
@@ -0,0 +1,221 @@
1
+ import Component from '@glimmer/component';
2
+ import { action } from '@ember/object';
3
+ import { cached, tracked } from '@glimmer/tracking';
4
+ import { argOrDefaultDecorator as argOrDefault } from '../../helpers/arg-or-default';
5
+ import MarkdownActions from '../../utils/markdown/markdown-actions';
6
+ import {
7
+ MODE_EDITING,
8
+ MODE_VIEWING
9
+ } from '../../utils/markdown/markdown-modes';
10
+ import {
11
+ defaultParsingPlugins,
12
+ defaultProcessingPlugins
13
+ } from '../../utils/markdown/plugins/markdown-default-plugins';
14
+ import { uniqueId } from '../../helpers/unique-id';
15
+ import unified from 'unified';
16
+ import * as MarkdownTooltipPlugin from '../../utils/markdown/plugins/markdown-tooltip';
17
+ import {
18
+ EuiMarkdownEditorUiPlugin,
19
+ EuiMarkdownAstNodePosition,
20
+ EuiMarkdownAstNode
21
+ } from '../../utils/markdown/markdown-types';
22
+ import { Processor } from 'unified';
23
+
24
+ export interface EuiMarkdownEditorArgs {
25
+ initialViewMode?: string;
26
+ editorId?: string;
27
+ uiPlugins: EuiMarkdownEditorUiPlugin[];
28
+ value: string;
29
+ onChange: (str: string) => void;
30
+ onParse: (
31
+ parseError: string | null,
32
+ parsed: { messages: string[]; ast: EuiMarkdownAstNode }
33
+ ) => void;
34
+ }
35
+
36
+ // function isNewLine(char: string | undefined): boolean {
37
+ // if (char == null) return true;
38
+ // return !!char.match(/[\r\n]/);
39
+ // }
40
+ // function padWithNewlinesIfNeeded(textarea: HTMLTextAreaElement, text: string) {
41
+ // const selectionStart = textarea.selectionStart;
42
+ // const selectionEnd = textarea.selectionEnd;
43
+
44
+ // // block parsing requires two leading new lines and none trailing, but we add an extra trailing line for readability
45
+ // const isPrevNewLine = isNewLine(textarea.value[selectionStart - 1]);
46
+ // const isPrevPrevNewLine = isNewLine(textarea.value[selectionStart - 2]);
47
+ // const isNextNewLine = isNewLine(textarea.value[selectionEnd]);
48
+
49
+ // // pad text with newlines as needed
50
+ // text = `${isPrevNewLine ? '' : '\n'}${isPrevPrevNewLine ? '' : '\n'}${text}${
51
+ // isNextNewLine ? '' : '\n'
52
+ // }`;
53
+ // return text;
54
+ // }
55
+
56
+ export default class EuiMarkdownEditorComponent extends Component<EuiMarkdownEditorArgs> {
57
+ // Defaults
58
+ @argOrDefault(defaultParsingPlugins)
59
+ declare parsingPluginList: typeof defaultParsingPlugins;
60
+
61
+ @argOrDefault(250) declare height: number | string;
62
+ @argOrDefault(500) declare maxHeight: number | string;
63
+ @argOrDefault(true) declare autoExpandPreview: boolean;
64
+
65
+ @argOrDefault(defaultProcessingPlugins)
66
+ declare processingPluginList: typeof defaultProcessingPlugins;
67
+
68
+ @tracked selectedNode: Node | null = null;
69
+ @tracked editorId = this.args.editorId ?? uniqueId();
70
+ @tracked viewMode = this.args.initialViewMode || MODE_EDITING;
71
+ @tracked textareaRef: HTMLTextAreaElement | null = null;
72
+ @tracked previewRef: HTMLDivElement | null = null;
73
+ @tracked editorToolbarRef: HTMLDivElement | null = null;
74
+ @tracked currentHeight: number | string = 250;
75
+ @tracked editorFooterHeight: number = 0;
76
+ @tracked editorToolbarHeight: number = 0;
77
+
78
+ markdownActions: MarkdownActions | null = null;
79
+
80
+ get toolbarPlugins() {
81
+ return [MarkdownTooltipPlugin.plugin, ...(this.args.uiPlugins || [])];
82
+ }
83
+
84
+ constructor(owner: unknown, args: EuiMarkdownEditorArgs) {
85
+ super(owner, args);
86
+ this.markdownActions = new MarkdownActions(
87
+ this.editorId,
88
+ this.toolbarPlugins
89
+ );
90
+ this.currentHeight = this.height;
91
+ }
92
+
93
+ get previewHeight() {
94
+ if (this.height === 'full') {
95
+ return `calc(100% - ${this.editorFooterHeight}px)`;
96
+ }
97
+ return `${this.currentHeight}px`;
98
+ }
99
+
100
+ get textAreaHeight() {
101
+ return this.height === 'full'
102
+ ? '100%'
103
+ : `calc(${(this.height as number) - this.editorFooterHeight}px)`;
104
+ }
105
+
106
+ get textAreaMaxHeight() {
107
+ return this.height !== 'full'
108
+ ? `${(this.maxHeight as number) - this.editorFooterHeight}px`
109
+ : '';
110
+ }
111
+
112
+ get editorToggleContainerHeight() {
113
+ return `calc(100% - ${this.editorToolbarHeight}px)`;
114
+ }
115
+
116
+ @action
117
+ onResize() {
118
+ if (this.textareaRef && this.isEditing && this.height !== 'full') {
119
+ const resizedTextareaHeight =
120
+ this.textareaRef.offsetHeight + this.editorFooterHeight;
121
+
122
+ this.currentHeight = resizedTextareaHeight;
123
+ }
124
+ }
125
+
126
+ @action
127
+ updateCurrentHeight() {
128
+ let { isPreviewing, autoExpandPreview, height, previewRef, currentHeight } =
129
+ this;
130
+ if (isPreviewing && autoExpandPreview && height !== 'full' && previewRef) {
131
+ if (previewRef.scrollHeight > currentHeight) {
132
+ // scrollHeight does not include the border or margin
133
+ // so we ask for the computed value for those,
134
+ // which is always in pixels because getComputedValue
135
+ // returns the resolved values
136
+ const elementComputedStyle = window.getComputedStyle(previewRef);
137
+ const borderWidth =
138
+ parseFloat(elementComputedStyle.borderTopWidth) +
139
+ parseFloat(elementComputedStyle.borderBottomWidth);
140
+ const marginWidth =
141
+ parseFloat(elementComputedStyle.marginTop) +
142
+ parseFloat(elementComputedStyle.marginBottom);
143
+
144
+ // then add an extra pixel for safety and because the scrollHeight value is rounded
145
+ const extraHeight = borderWidth + marginWidth + 1;
146
+
147
+ this.currentHeight = previewRef.scrollHeight + extraHeight;
148
+ }
149
+ }
150
+ }
151
+
152
+ @action
153
+ setTextAreaRef(ref: HTMLTextAreaElement) {
154
+ this.textareaRef = ref;
155
+ }
156
+
157
+ @action
158
+ setEditorToolbarRef(ref: HTMLDivElement) {
159
+ this.editorToolbarRef = ref;
160
+ this.editorToolbarHeight = ref.offsetHeight;
161
+ }
162
+
163
+ @action
164
+ replaceNode(position: EuiMarkdownAstNodePosition, next: string) {
165
+ let value = this.args.value;
166
+ const leading = value.substr(0, position.start.offset);
167
+ const trailing = value.substr(position.end.offset);
168
+ this.args.onChange?.(`${leading}${next}${trailing}`);
169
+ }
170
+
171
+ get isEditing() {
172
+ return this.viewMode === MODE_EDITING;
173
+ }
174
+
175
+ get isPreviewing() {
176
+ return this.viewMode === MODE_VIEWING;
177
+ }
178
+
179
+ @action
180
+ setViewMode() {
181
+ this.viewMode = this.isPreviewing ? MODE_EDITING : MODE_VIEWING;
182
+ }
183
+
184
+ @cached
185
+ get parser() {
186
+ const Compiler = (tree: any) => {
187
+ return tree;
188
+ };
189
+
190
+ function identityCompiler(this: Processor) {
191
+ this.Compiler = Compiler;
192
+ }
193
+ return unified().use(this.parsingPluginList).use(identityCompiler);
194
+ }
195
+
196
+ @cached
197
+ get parsed() {
198
+ try {
199
+ const parsed = this.parser.processSync(this.args.value);
200
+ return [parsed, null];
201
+ } catch (e) {
202
+ return [null, e];
203
+ }
204
+ }
205
+
206
+ @action
207
+ onParse() {
208
+ if (this.args.onParse) {
209
+ const [parsed, parseError] = this.parsed;
210
+ const onParse = this.args.onParse;
211
+ const messages = parsed ? parsed.messages : [];
212
+ const ast = parsed ? parsed.result ?? parsed.contents : null;
213
+ onParse(parseError, { messages, ast });
214
+ }
215
+ }
216
+
217
+ @action
218
+ setSelectedNode(node: Node) {
219
+ this.selectedNode = node;
220
+ }
221
+ }
@@ -0,0 +1,21 @@
1
+ <div
2
+ class={{class-names
3
+ "euiMarkdownEditorDropZone"
4
+ (if this.isDragging "euiMarkdownEditorDropZone--isDragging")
5
+ (if @hasUnacceptedItems "euiMarkdownEditorDropZone--hasError")
6
+ (if this.isDraggingError "euiMarkdownEditorDropZone--isDraggingError")
7
+ }}
8
+ >
9
+ {{yield}}
10
+ <EuiMarkdownEditorFooter
11
+ @uiPlugins={{@uiPlugins}}
12
+ {{!-- openFiles={() => {
13
+ setHasUnacceptedItems(false);
14
+ open();
15
+ }} --}}
16
+ @isUploadingFiles={{this.isUploadingFiles}}
17
+ @hasUnacceptedItems={{@hasUnacceptedItems}}
18
+ {{! dropHandlers={dropHandlers} }}
19
+ @errors={{@errors}}
20
+ />
21
+ </div>
@@ -0,0 +1,5 @@
1
+ import Component from '@glimmer/component';
2
+
3
+ export interface EuiMarkdownEditorDropZoneArgs {}
4
+
5
+ export default class EuiMarkdownEditorDropZoneComponent extends Component<EuiMarkdownEditorDropZoneArgs> {}
@@ -0,0 +1,108 @@
1
+ <div class="euiMarkdownEditorFooter">
2
+ <div class="euiMarkdownEditorFooter__actions">
3
+
4
+ {{#if @isUploadingFiles}}
5
+ {{! pending implementation}}
6
+ <EuiButtonIcon
7
+ @iconType={{component "eui-loading-spinner"}}
8
+ {{! aria-label={ariaLabels.uploadingFiles} }}
9
+ />
10
+ {{/if}}
11
+ {{#if (and @errors @errors.length)}}
12
+ <EuiPopover
13
+ @isOpen={{this.isPopoverOpen}}
14
+ @closePopover={{set this "isPopoverOpen" false}}
15
+ >
16
+ <:button>
17
+ <EuiButtonEmpty
18
+ @iconType="crossInACircleFilled"
19
+ @size="s"
20
+ @color="danger"
21
+ {{! aria-label={ariaLabels.showSyntaxErrors} }}
22
+ {{on "click" (set this "isPopoverOpen" (not this.isPopoverOpen))}}
23
+ >
24
+ {{@errors.length}}
25
+ </EuiButtonEmpty>
26
+ </:button>
27
+ </EuiPopover>
28
+ {{/if}}
29
+ </div>
30
+ <EuiButtonIcon
31
+ class="euiMarkdownEditorFooter__help"
32
+ @iconType={{this.markdownLogo}}
33
+ @color="text"
34
+ @useSvg={{true}}
35
+ {{! aria-label={ariaLabels.showMarkdownHelp} }}
36
+ {{on "click" (set this "isShowingHelp" (not this.isShowingHelp))}}
37
+ />
38
+
39
+ {{#if this.isShowingHelp}}
40
+ <EuiOverlayMask>
41
+ <EuiModal @onClose={{set this "isShowingHelp" false}}>
42
+ <EuiModalHeader>
43
+ <EuiTitle>
44
+ <h3>
45
+ Syntax Help
46
+ {{! <EuiI18n
47
+ token="euiMarkdownEditorFooter.syntaxTitle"
48
+ default="Syntax help"
49
+ /> }}
50
+ </h3>
51
+ </EuiTitle>
52
+ </EuiModalHeader>
53
+ <EuiModalBody>
54
+
55
+ <EuiText>
56
+ <p>The editor uses</p>
57
+ <a
58
+ href="https://github.github.com/gfm/"
59
+ target="_blank"
60
+ rel="noreferrer noopener"
61
+ >
62
+ Github flavored markdown
63
+ </a>
64
+ <p>You can also utilize these additional syntax plugins to add rich
65
+ content to yoru text.</p>
66
+
67
+ {{! <EuiI18n
68
+ tokens={[
69
+ 'euiMarkdownEditorFooter.descriptionPrefix',
70
+ 'euiMarkdownEditorFooter.descriptionSuffix',
71
+ ]}
72
+ defaults={[
73
+ 'This editor uses',
74
+ 'You can also utilize these additional syntax plugins to add rich content to your text.',
75
+ ]}>
76
+ {([descriptionPrefix, descriptionSuffix]: ReactChild[]) => (
77
+ <p>
78
+ {descriptionPrefix}{' '}
79
+ <a
80
+ href="https://github.github.com/gfm/"
81
+ target="_blank">
82
+ Github flavored markdown
83
+ </a>
84
+ . {descriptionSuffix}
85
+ </p>
86
+ )}
87
+ </EuiI18n> }}
88
+ </EuiText>
89
+ <EuiHorizontalRule />
90
+ {{#each @uiPlugins as |uiPlugin|}}
91
+ {{#if uiPlugin.helpText}}
92
+ <EuiTitle size="xxs">
93
+ <p>
94
+ <strong>{{uiPlugin.name}}</strong>
95
+ </p>
96
+ </EuiTitle>
97
+ <EuiSpacer size="s" />
98
+ <EuiMarkdownFormat @value={{uiPlugin.helpText}} />
99
+ <EuiSpacer size="l" />
100
+
101
+ {{/if}}
102
+ {{/each}}
103
+ </EuiModalBody>
104
+ </EuiModal>
105
+ </EuiOverlayMask>
106
+
107
+ {{/if}}
108
+ </div>
@@ -0,0 +1,20 @@
1
+ import Component from '@glimmer/component';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { getOwner } from '@ember/application';
4
+
5
+ export interface EuiMarkdownEditorFooterArgs {}
6
+
7
+ export default class EuiMarkdownEditorFooterComponent extends Component<EuiMarkdownEditorFooterArgs> {
8
+ @tracked isPopoverOpen = false;
9
+ @tracked isShowingHelp = false;
10
+
11
+ get svgPath() {
12
+ const config = getOwner(this).resolveRegistration('config:environment');
13
+ const svgPath = config?.['@ember-eui/core']?.svgPath || 'svg';
14
+ return svgPath;
15
+ }
16
+
17
+ get markdownLogo() {
18
+ return `${this.svgPath}/markdown-logo`;
19
+ }
20
+ }
@@ -0,0 +1,8 @@
1
+ <textarea
2
+ class="euiMarkdownEditorTextArea"
3
+ rows="6"
4
+ ...attributes
5
+ {{style (hash height=@height maxHeight=@maxHeight)}}
6
+ >
7
+ {{yield}}
8
+ </textarea>