Skip to content

Commit

Permalink
feat(wysiwyg-markdown-editor): initial commit
Browse files Browse the repository at this point in the history
Darran Boyd committed Jan 30, 2025
1 parent 120bf36 commit 97ebac2
Showing 21 changed files with 2,373 additions and 181 deletions.
5 changes: 2 additions & 3 deletions .gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 8 additions & 3 deletions .projen/deps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .projenrc.ts
Original file line number Diff line number Diff line change
@@ -16,4 +16,10 @@ monorepo.addImplicitDependency(appProject, uiProject);
monorepo.addImplicitDependency(infraProject, appProject);
monorepo.addImplicitDependency(browserExtensionProject, appProject);

monorepo.package.addPackageResolutions(...[
"**/@typescript-eslint/[email protected]",
"**/@typescript-eslint/[email protected]"
],
);

monorepo.synth();
7 changes: 4 additions & 3 deletions package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/threat-composer-app-browser-extension/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/threat-composer-app/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/threat-composer-app/.projen/deps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/threat-composer-app/package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/threat-composer-infra/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/threat-composer-infra/.projen/deps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/threat-composer-infra/package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/threat-composer/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion packages/threat-composer/.projen/deps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions packages/threat-composer/.projen/tasks.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/threat-composer/package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -18,22 +18,27 @@ import Container from '@cloudscape-design/components/container';
import FormField from '@cloudscape-design/components/form-field';
import Header from '@cloudscape-design/components/header';
import SpaceBetween from '@cloudscape-design/components/space-between';
import { FC, useState, useCallback, useMemo, useEffect } from 'react';
import { Mode } from '@cloudscape-design/global-styles';
import { MDXEditor, MDXEditorMethods, DiffSourceToggleWrapper, ListsToggle, toolbarPlugin, diffSourcePlugin, linkPlugin, linkDialogPlugin, UndoRedo, headingsPlugin, quotePlugin, markdownShortcutPlugin, BoldItalicUnderlineToggles, BlockTypeSelect, CodeToggle, CreateLink, InsertCodeBlock, InsertImage, imagePlugin, InsertTable, tablePlugin, listsPlugin } from '@mdxeditor/editor';
import '@mdxeditor/editor/style.css';
import { FC, useState, useCallback, useMemo, useEffect, useRef } from 'react';
import { useApplicationInfoContext } from '../../../contexts/ApplicationContext/context';
import { ApplicationInfoSchema, EditableComponentBaseProps } from '../../../customTypes';
import ContentLayout from '../../generic/ContentLayout';
import Input from '../../generic/Input';
import MarkdownEditor from '../../generic/MarkdownEditor';
import MarkdownViewer from '../../generic/MarkdownViewer';
import { useThemeContext } from '../../generic/ThemeProvider';


const ApplicationInfo: FC<EditableComponentBaseProps> = ({
onEditModeChange,
MarkdownEditorComponentType = MarkdownEditor,
}) => {
const { applicationInfo, setApplicationInfo } = useApplicationInfoContext();
const [editMode, setEditMode] = useState(!applicationInfo.name && !applicationInfo.description);
const [content, setContent] = useState('');
const [name, setName] = useState('');
const mdxEditorRef = useRef<MDXEditorMethods>(null);
const { theme } = useThemeContext();

useEffect(() => {
onEditModeChange?.(editMode);
@@ -42,7 +47,7 @@ const ApplicationInfo: FC<EditableComponentBaseProps> = ({
const handleSaveApplicationInfo = useCallback(() => {
setApplicationInfo(prev => ({
...prev,
description: content,
description: mdxEditorRef.current?.getMarkdown(),
name,
}));
setEditMode(false);
@@ -77,13 +82,39 @@ const ApplicationInfo: FC<EditableComponentBaseProps> = ({
placeholder='Enter application name'
/>
</FormField>
<MarkdownEditorComponentType
value={content}
onChange={setContent}
label='Description'
parentHeaderLevel='h2'
validateData={ApplicationInfoSchema.shape.description.safeParse}
/>
<MDXEditor
ref={mdxEditorRef}
markdown={applicationInfo.description || ''}
className = {theme == Mode.Dark ? 'dark-theme dark-editor' : 'light-theme light-editor'}
plugins={[
toolbarPlugin({
toolbarContents: () => (
<>
<DiffSourceToggleWrapper>
<BoldItalicUnderlineToggles options={['Bold', 'Italic']}/>
<BlockTypeSelect />
<CodeToggle />
<CreateLink />
<InsertImage />
<InsertTable />
<ListsToggle options={['bullet', 'number']}/>
<InsertCodeBlock />
<UndoRedo />
</DiffSourceToggleWrapper>
</>
),
}),
tablePlugin(),
diffSourcePlugin({ viewMode: 'rich-text', diffMarkdown: applicationInfo.description || '' }),
markdownShortcutPlugin(),
listsPlugin(),
quotePlugin(),
headingsPlugin(),
linkPlugin(),
linkDialogPlugin(),
imagePlugin( { disableImageResize: true }),
]
} />
</SpaceBetween>) :
(<MarkdownViewer>
{applicationInfo.description || ''}
Original file line number Diff line number Diff line change
@@ -18,12 +18,16 @@ import Button from '@cloudscape-design/components/button';
import Container from '@cloudscape-design/components/container';
import Header from '@cloudscape-design/components/header';
import SpaceBetween from '@cloudscape-design/components/space-between';
import { FC, useCallback, useState, useMemo, useEffect } from 'react';
import { Mode } from '@cloudscape-design/global-styles';
import { MDXEditor, MDXEditorMethods, DiffSourceToggleWrapper, ListsToggle, toolbarPlugin, diffSourcePlugin, linkPlugin, linkDialogPlugin, UndoRedo, headingsPlugin, quotePlugin, markdownShortcutPlugin, BoldItalicUnderlineToggles, BlockTypeSelect, CodeToggle, CreateLink, InsertCodeBlock, InsertImage, imagePlugin, InsertTable, tablePlugin, listsPlugin } from '@mdxeditor/editor';
import { FC, useCallback, useState, useMemo, useEffect, useRef } from 'react';
import { BaseImageInfo, EditableComponentBaseProps } from '../../../customTypes';
import '@mdxeditor/editor/style.css';
import imageStyles from '../../../styles/image';
import ContentLayout from '../../generic/ContentLayout';
import { useThemeContext } from '../../generic/ThemeProvider';
import ImageEdit from '../ImageEdit';
import MarkdownEditor, { MarkdownEditorProps } from '../MarkdownEditor';
import { MarkdownEditorProps } from '../MarkdownEditor';
import MarkdownViewer from '../MarkdownViewer';

export interface BaseDiagramInfoProps extends EditableComponentBaseProps {
@@ -39,13 +43,13 @@ const BaseDiagramInfo: FC<BaseDiagramInfoProps> = ({
diagramTitle,
entity,
onConfirm,
validateData,
onEditModeChange,
MarkdownEditorComponentType = MarkdownEditor,
}) => {
const [editMode, setEditMode] = useState(!entity.description && !entity.image);
const [image, setImage] = useState<string>('');
const [content, setContent] = useState('');
const mdxEditorRef = useRef<MDXEditorMethods>(null);
const { theme } = useThemeContext();

useEffect(() => {
onEditModeChange?.(editMode);
@@ -54,7 +58,7 @@ const BaseDiagramInfo: FC<BaseDiagramInfoProps> = ({
const handleSaveDiagramInfo = useCallback(() => {
onConfirm({
image,
description: content,
description: mdxEditorRef.current?.getMarkdown(),
});
setEditMode(false);
}, [image, content, onConfirm]);
@@ -78,13 +82,40 @@ const BaseDiagramInfo: FC<BaseDiagramInfoProps> = ({
>
<Container>
{editMode ? (<SpaceBetween direction='vertical' size='s'>
<MarkdownEditorComponentType
label='Introduction'
value={content}
onChange={setContent}
parentHeaderLevel='h3'
validateData={validateData}
/>
<Header variant='h3'>Introduction</Header>
<MDXEditor
ref={mdxEditorRef}
markdown={entity.description || ''}
className={theme == Mode.Dark ? 'dark-theme dark-editor' : 'light-theme light-editor'}
plugins={[
toolbarPlugin({
toolbarContents: () => (
<>
<DiffSourceToggleWrapper>
<BoldItalicUnderlineToggles options={['Bold', 'Italic']} />
<BlockTypeSelect />
<CodeToggle />
<CreateLink />
<InsertImage />
<InsertTable />
<ListsToggle options={['bullet', 'number']} />
<InsertCodeBlock />
<UndoRedo />
</DiffSourceToggleWrapper>
</>
),
}),
tablePlugin(),
diffSourcePlugin({ viewMode: 'rich-text', diffMarkdown: entity.description || '' }),
markdownShortcutPlugin(),
listsPlugin(),
quotePlugin(),
headingsPlugin(),
linkPlugin(),
linkDialogPlugin(),
imagePlugin({ disableImageResize: true }),
]
} />
<Header variant='h3'>{headerTitle} Diagram</Header>
<ImageEdit value={image} onChange={setImage} />
</SpaceBetween>) :
1 change: 1 addition & 0 deletions projenrc/ui-components.ts
Original file line number Diff line number Diff line change
@@ -42,6 +42,7 @@ class ThreatComposerUIComponentsProject extends TypeScriptProject {
"zod",
"unified",
"yaml",
"@mdxeditor/editor",
],
devDeps: [
"@cloudscape-design/jest-preset",
2,383 changes: 2,248 additions & 135 deletions yarn.lock

Large diffs are not rendered by default.

0 comments on commit 97ebac2

Please sign in to comment.