Skip to content

Commit

Permalink
[Feature Branch] EuiMarkdownEditor (#3522)
Browse files Browse the repository at this point in the history
* WIP: Add markdown_editor component

* WIP: commit auto-added i18n tokens

* Adding button toggle for previewing

* Adding toolbar component

* Adding file picker initial structure

* Adding text area component

* Buttons order

* Moving markdown editor to docs form section

* Improving file picker

* Adding dropZone component and preview styles

* Fixing height issue while resizing textarea

* Small UI fix

* Improving markdown example

* remove showdown, since it wasn't being used

* Adding code highlight

* Better coding highlight

* Replacing UglifyJsPlugin with TerserPlugin

* Adding button enter key and buttons tooltips

* More code highlight fixes

* Markdown editor plugins (#3457)

* Refactored EuiMarkdownEditor and EuiMarkdownFormat to prep for future work

* pr feedback

* [markdown] chart & tooltip plugins (#3479)

* chart & tooltip plugins

* Change tooltip markdown plugin markdown format

* Fixed error with empty tooltip tag

* [Markdown] Checkbox plugin (#3493)

* Checkbox plugin

* Better checkbox interaction formatting

* Use monospace font in markdown editor

* [EuiMarkdownEditor] Improve markdown editor font (#3525)

* Improving font family and text area font styles

* Text color and text babckground

* Adding eui font family

* euiFormControlText

* Small fix

* Refactoring some styles

* Removing unecessary padding

* Re-enable default markdown list parsing (#3531)

* [Markdown] Allow toolbar buttons to present modals to create/edit tags (#3506)

* Allow EuiMarkdownEditor's ui buttons trigger interactive modals for creating & editing tags

* export two internal markdown types that are needed externally when generating eui.d.ts

* Re-enable the default markdown list parsing/display, but keep EUI's checkbox override

* Give EuiMarkdownEditorTextArea a displayName

* Enable undo/redo for markdown editor, apart from firefox (#3582)

* Enable undo/redo for markdown editor, apart from firefox

* Add test-and-retry logic to insertText to account for ability to focus the text area before brute forcing

* Added AST & info/fail message reporting to application; added info messages to tooltip plugin and fail message to chart configuration parsing (#3602)

* Add an imperative ref to EuiMarkdownEditor (#3622)

* Add an imperative ref to EuiMarkdownEditor, exposing the textarea element and replaceNode method

* Remove textareaRef from two hook dependency arrays

* eslint errors

* Add a markdown help modal, move tooltip & checkbox plugins into src (#3636)

* Move checkbox and tooltip markdown plugins into eui src, add helpText to ui plugins

* Adding footer initial styles

* Adding error popover

* Fixing uploading files icon

* wire up errors

* modal help text

* better modal text

* blerg, react color

* toggle button for editor ast

* Ignoring ts errors and fixing sass lint errors

* Displaying always error info

* Adding checkmark button

* fix markdown test

* Added aria-label and aria-labelledby props to markdown editor

* Fix i18n token name for markdown errors title

* Reverting displaying errors

Co-authored-by: miukimiu <elizabet.oliveira@elastic.co>
Co-authored-by: Dave Snider <dave.snider@gmail.com>

* [EuiMarkdownEditor] Improving markdown format styles (#3534)

* Improving markdown format styles

* Transforming px to em

* Renaming variable

* Adding descriptions and alpha values

* hr more similar to EuiHorizontalRule

* [EuiMarkdownEditor] Better styles and class names (#3697)

* Better styles and classnames

* md footer height

* snapshot

* preventing the text area of loosing focus when clicking on an action button

* Add types to markdown editor (#3703)

* Plugin types

* Rehype / hast / unist node types

* Make typescript happy with markdown editor and dependencies

* Types for markdown AST nodes and errors

* Don't scan any .d.ts file for internationalization strings

* Adding missing types and dependency

* Fixing firefox text area margin (#3802)

* Markdown Format / Editor documentation + features (#3696)

Separates `EuiMarkdownFormat` into its own component. Adds documentation.

* [Markdown editor] drag and drop api, functionality (#3748)

* Initial markdown drag-n-drop api

* Properly insert multiple drag-and-drop results

* Update logic for markdown supported files message display

* disable upload interaction if no drop handlers are provided

* Upload error button styles

* pr feedback

* Only accept supported file types in the markdown file selection dialog

* Drag and drop animation

* small changes

* Add some cross-browser stability when dealing with unsupported drop files

Co-authored-by: miukimiu <elizabet.oliveira@elastic.co>

* Feature/markdown editor cleanup (#3830)

* Sort drag&drop file extensions when displaying

* mark markdown components as new and in beta

* Get EuiMarkdownEditor Props to render

* Update markdown's plugin prop docs based on existing writeups

* Prevent markdown plugin extensions from interacting with each other (#3842)

* Simplify the markdown editor's plugin API (#3843)

* Add a default remark->rehype node handler to simplify plugin development

* Update documentation

* Add license info around markdown tag processing; Support block-level tag insertions (#3867)

* changelog

* Improved, and proper, types for the markdown editor's usage in downstream apps (#3893)

* Fixes some ARIA issues in EuiMarkdownEditor (#3899)

* Support aria-describedby to link errors. Include file support message in upload button's aria-label

* Change markdown footer element to a div

Co-authored-by: i-a-n <ian@union.io>
Co-authored-by: Dave Snider <dave.snider@gmail.com>
Co-authored-by: Chandler Prall <chandler.prall@gmail.com>
  • Loading branch information
4 people authored Aug 12, 2020
1 parent 7958612 commit 81f22fe
Show file tree
Hide file tree
Showing 49 changed files with 5,835 additions and 41 deletions.
6 changes: 6 additions & 0 deletions .stylelintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"rules": {
"number-leading-zero": "never",
"color-hex-case": "upper"
}
}
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
- Update `createTheme` to apply latest changes to elastic charts `Theme`. ([#3792](https://github.com/elastic/eui/pull/3792))
- Added icons for `appSearchApp` and `workplaceSearchApp` to `EuiIcon` ([#3859](https://github.com/elastic/eui/pull/3859))
- Added `unlink` glyph to `EuiIcon` ([#3869](https://github.com/elastic/eui/pull/3869))
- Added `EuiMarkdownEditor` and `EuiMarkdownFormat` components ([#3522](https://github.com/elastic/eui/pull/3522))

**Bug fixes**

Expand Down
15 changes: 14 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"@types/react-input-autosize": "^2.0.2",
"@types/react-virtualized-auto-sizer": "^1.0.0",
"@types/react-window": "^1.8.1",
"@types/vfile-message": "^2.0.0",
"chroma-js": "^2.0.4",
"classnames": "^2.2.5",
"highlight.js": "^9.12.0",
Expand All @@ -66,15 +67,25 @@
"prop-types": "^15.6.0",
"react-ace": "^7.0.5",
"react-beautiful-dnd": "^13.0.0",
"react-dropzone": "^10.2.1",
"react-focus-on": "^3.4.1",
"react-input-autosize": "^2.2.2",
"react-is": "~16.3.0",
"react-virtualized-auto-sizer": "^1.0.2",
"react-window": "^1.8.5",
"rehype-raw": "^4.0.1",
"rehype-react": "^6.0.0",
"rehype-stringify": "^6.0.1",
"remark-emoji": "^2.1.0",
"remark-highlight.js": "^5.2.0",
"remark-parse": "^7.0.2",
"remark-rehype": "^7.0.0",
"resize-observer-polyfill": "^1.5.0",
"tabbable": "^3.0.0",
"text-diff": "^1.0.1",
"uuid": "^3.1.0"
"unified": "^8.4.2",
"uuid": "^3.1.0",
"vfile": "^4.1.1"
},
"devDependencies": {
"@babel/cli": "^7.8.3",
Expand Down Expand Up @@ -174,6 +185,7 @@
"postcss-loader": "^2.0.8",
"pre-commit": "^1.2.2",
"prettier": "^1.19.1",
"prettier-stylelint": "^0.4.2",
"prompt": "^1.0.0",
"prop-types": "^15.6.0",
"puppeteer": "^2.0.0",
Expand All @@ -198,6 +210,7 @@
"shelljs": "^0.8.1",
"start-server-and-test": "^1.1.4",
"style-loader": "^0.19.0",
"terser-webpack-plugin": "^2.3.5",
"typescript": "3.7.2",
"uglifyjs-webpack-plugin": "^2.0.1",
"url-loader": "^1.0.1",
Expand Down
2 changes: 1 addition & 1 deletion scripts/babel/fetch-i18n-strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ const files = glob.sync(
'**/*.@(js|ts|tsx)',
{ cwd: srcDir, realpath: true },
).filter(filepath => {
if (filepath.endsWith('index.d.ts')) return false;
if (filepath.endsWith('.d.ts')) return false;
if (filepath.endsWith('test.ts')) return false;
if (filepath.endsWith('test.tsx')) return false;
if (filepath.endsWith('test.js')) return false;
Expand Down
8 changes: 8 additions & 0 deletions scripts/babel/proptypes-from-ts-props/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ function resolveArrayTypeToPropTypes(node, state) {
* - Arrays
* - MouseEventHandler is interpretted as functions
* - ExclusiveUnion custom type
* - OneOf custom type
* - defined types/interfaces (found during initial program body parsing)
* Returns `null` for unresolvable types
* @param node
Expand Down Expand Up @@ -342,6 +343,13 @@ function resolveIdentifierToPropTypes(node, state) {
return propTypes;
}

if (identifier.name === 'OneOf') {
// the second type parameter is ignorable as it is a subset of the first,
// and the OneOf operation cannot be well-described by proptypes
const [sourceTypes] = node.typeParameters.params;
return getPropTypesForNode(sourceTypes, true, state);
}

// Lookup this identifier from types/interfaces defined in code
const identifierDefinition = typeDefinitions[identifier.name];

Expand Down
18 changes: 16 additions & 2 deletions src-docs/src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ import { ListGroupExample } from './views/list_group/list_group_example';

import { LoadingExample } from './views/loading/loading_example';

import { MarkdownEditorExample } from './views/markdown_editor/mardown_editor_example';

import { MarkdownFormatExample } from './views/markdown_editor/mardown_format_example';

import { MarkdownPluginExample } from './views/markdown_editor/markdown_plugin_example';

import { ModalExample } from './views/modal/modal_example';

import { MutationObserverExample } from './views/mutation_observer/mutation_observer_example';
Expand Down Expand Up @@ -377,7 +383,6 @@ const navigation = [
BadgeExample,
CallOutExample,
CardExample,
CodeExample,
CommentListExample,
DescriptionListExample,
DragAndDropExample,
Expand Down Expand Up @@ -407,7 +412,6 @@ const navigation = [
SuperSelectExample,
ComboBoxExample,
ColorPickerExample,
CodeEditorExample,
DatePickerExample,
ExpressionExample,
FilterGroupExample,
Expand All @@ -418,6 +422,16 @@ const navigation = [
SuperDatePickerExample,
].map(example => createExample(example)),
},
{
name: 'Editors & syntax',
items: [
MarkdownFormatExample,
MarkdownEditorExample,
MarkdownPluginExample,
CodeEditorExample,
CodeExample,
].map(example => createExample(example)),
},
{
name: 'Elastic Charts',
items: [
Expand Down
99 changes: 99 additions & 0 deletions src-docs/src/views/markdown_editor/mardown_editor_example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import React, { Fragment } from 'react';

import { renderToHtml } from '../../services';

import { GuideSectionTypes } from '../../components';

import {
EuiMarkdownEditor,
EuiText,
EuiSpacer,
EuiCode,
} from '../../../../src/components';

import { Link } from 'react-router-dom';

import MarkdownEditor from './markdown_editor';
const markdownEditorSource = require('!!raw-loader!./markdown_editor');
const markdownEditorHtml = renderToHtml(MarkdownEditor);

import MarkdownEditorErrors from './markdown_editor_errors';
const markdownEditorErrorsSource = require('!!raw-loader!./markdown_editor_errors');
const markdownEditorErrorsHtml = renderToHtml(MarkdownEditorErrors);

export const MarkdownEditorExample = {
title: 'Markdown editor',
beta: true,
isNew: true,
intro: (
<Fragment>
<EuiText>
<p>
<strong>EuiMarkdownEditor</strong> provides a markdown authoring
experience for the user. The component consists of a toolbar, text
area, and a drag-and-drop zone to accept files (if configured to do
so). There are two modes: a textarea that keeps track of cursor
position, and a rendered preview mode that is powered by{' '}
<strong>
<Link to="/editors-syntax/markdown-format/">EuiMarkdownFormat</Link>
</strong>
. State is maintained between the two and it is possible to pass
changes from the preview area to the textarea and vice versa.
</p>
</EuiText>
<EuiSpacer size="xxl" />
</Fragment>
),
sections: [
{
source: [
{
type: GuideSectionTypes.JS,
code: markdownEditorSource,
},
{
type: GuideSectionTypes.HTML,
code: markdownEditorHtml,
},
],
title: 'Base editor',
text: (
<p>
The base editor can render basic markdown along with some built-in
plugins.
</p>
),
props: {
EuiMarkdownEditor,
},
demo: <MarkdownEditor />,
},
{
source: [
{
type: GuideSectionTypes.JS,
code: markdownEditorErrorsSource,
},
{
type: GuideSectionTypes.HTML,
code: markdownEditorErrorsHtml,
},
],
title: 'Error handling and feedback',
text: (
<p>
The <EuiCode>errors</EuiCode> prop allows you to pass an array of
errors if syntax is malformed. The below example starts with an
incomplete tooltip tag, showing this error message by default. These
errors are meant to be ephemeral and part of the editing experience.
They should not be a substitute for{' '}
<Link to="/forms/form-validation">form validation</Link>.
</p>
),
props: {
EuiMarkdownEditor,
},
demo: <MarkdownEditorErrors />,
},
],
};
96 changes: 96 additions & 0 deletions src-docs/src/views/markdown_editor/mardown_format_example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import React, { Fragment } from 'react';

import { renderToHtml } from '../../services';

import { GuideSectionTypes } from '../../components';

import {
EuiMarkdownFormat,
EuiText,
EuiSpacer,
} from '../../../../src/components';

import { Link } from 'react-router-dom';

import MarkdownFormat from './markdown_format';
const markdownFormatSource = require('!!raw-loader!./markdown_format');
const markdownFormatHtml = renderToHtml(MarkdownFormat);

import MarkdownFormatSink from './markdown_format_sink';
const markdownFormatSinkSource = require('!!raw-loader!./markdown_format_sink');
const markdownFormatSinkHtml = renderToHtml(MarkdownFormatSink);

export const MarkdownFormatExample = {
title: 'Markdown format',
beta: true,
isNew: true,
intro: (
<Fragment>
<EuiText>
<p>
<strong>EuiMarkdownFormat</strong> is a read-only way to render
markdown-style content in a page. It is a peer component to{' '}
<strong>
<Link to="/editors-syntax/markdown-editor/">EuiMarkdownEditor</Link>
</strong>{' '}
and has the ability to be modified by additional{' '}
<Link to="/editors-syntax/markdown-plugins">markdown plugins</Link>.
</p>
</EuiText>
<EuiSpacer size="xxl" />
</Fragment>
),
sections: [
{
source: [
{
type: GuideSectionTypes.JS,
code: markdownFormatSource,
},
{
type: GuideSectionTypes.HTML,
code: markdownFormatHtml,
},
],
title: 'Built in plugins',
text: (
<p>
<strong>EuiMarkdownFormat</strong> is a wrapper that will render
Markdown provided. EuiMarkdownFormat uses{' '}
<Link to="https://github.com/remarkjs/remark)">Remark</Link> by
default. The translation layer automatically substitutes raw HTML
output with their EUI equivilant. This means anchor and code blocks
will become <strong>EuiLink</strong> and <strong>EuiCodeBlock</strong>{' '}
components respectively.
</p>
),
props: {
EuiMarkdownFormat,
},
demo: <MarkdownFormat />,
},
{
source: [
{
type: GuideSectionTypes.JS,
code: markdownFormatSinkSource,
},
{
type: GuideSectionTypes.HTML,
code: markdownFormatSinkHtml,
},
],
title: 'Kitchen sink',
text: (
<p>
This example shows of all the styling and markup possibilities. It is
mostly used for testing.
</p>
),
props: {
EuiMarkdownFormat,
},
demo: <MarkdownFormatSink />,
},
],
};
Loading

0 comments on commit 81f22fe

Please sign in to comment.