Skip to content

Commit

Permalink
[chore] update README.md, support touch events
Browse files Browse the repository at this point in the history
  • Loading branch information
ousc committed Dec 20, 2023
1 parent a943c4d commit 7cc3d66
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 151 deletions.
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,16 +170,16 @@ export class AppComponent {

### API

| Property | Description | Type | Default |
|-------------------|-------------------------------------------------------------------|----------------------------|---------|
| `[classList]` | editor element class names | `string[]` | `[]` |
| `[editorConfig]` | config before Editor.create() | `NgMilkdownEditorConfig` | `[]` |
| `[plugins]` | milkdown plugin to use | `NgMilkdownPlugin[]` | `[]` |
| `[loading]` | set the loading status of editor | `boolean` | `true` |
| `[spinner]` | Custom spinner | `TemplateRef<any>` | - |
| `[ngModel]` | current value , double binding | `DefaultValue` | - |
| `(ngModelChange)` | callback when markdown change | `EventEmitter<DefaultValue>` | - |
| `(onReady)` | A callback function, can be executed when editor has bean created | `Editor` | - |
| Property | Description | Type | Default |
|-------------------|-------------------------------------------------------------------|--------------------------|------------------------|
| `[classList]` | editor element class names | `string[]` | `[]` |
| `[editorConfig]` | config before Editor.create() | `NgMilkdownEditorConfig` | `(ctx: Ctx) => void 0` |
| `[plugins]` | milkdown plugin to use | `NgMilkdownPlugin[]` | `[]` |
| `[loading]` | set the loading status of editor | `boolean` | `true` |
| `[spinner]` | Custom spinner | `TemplateRef<any>` | - |
| `[ngModel]` | current value , double binding | `DefaultValue` | - |
| `(ngModelChange)` | callback when markdown change | `EventEmitter<string>` | - |
| `(onReady)` | A callback function, can be executed when editor has bean created | `Editor` | - |

## OutOfBox Plugins

Expand Down
2 changes: 1 addition & 1 deletion src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
@if (editor && !editor.loading) {
<tool-bar class="opacity-80" [provider]="provider"/>
}
<div class="h-full overflow-auto overscroll-none ctn left-0 right-0 mx-auto flex flex-col px-4">
<div class="h-full overflow-auto overscroll-none ctn flex flex-col px-4">
<ng-prosemirror-adapter-provider #provider>
<ng-milkdown
*ngIf="value"
Expand Down
2 changes: 1 addition & 1 deletion src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ export class AppComponent implements OnInit {
plugins: NgMilkdownPlugin[] = null;

onChange(markdownText: any) {
// console.log('markdown changed!', {markdownText})
console.log('markdown changed!', {markdownText})
}

config = (ctx: any) => {
Expand Down
4 changes: 3 additions & 1 deletion src/app/components/slash/slash.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
<li class="cursor-pointer px-6 py-3"
[class]="selected === $index ? ['bg-gray-200', 'dark:bg-gray-500'] : []"
(mousemove)="selected = $index"
(mousedown)="action(onPick)">
(mousedown)="action(onPick)"
(touchstart)="selected = $index;action(onPick)"
>
<div class="flex items-center gap-2">
<span class="material-symbols-outlined text-nord-10 dark:text-nord-9">{{ item.icon }}</span>
<span>{{ item.label }}</span>
Expand Down
35 changes: 17 additions & 18 deletions src/app/components/slash/slash.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Component} from '@angular/core';
import {CmdKey, commandsCtx, editorViewCtx} from "@milkdown/core";
import {commandsCtx, editorViewCtx} from "@milkdown/core";
import {
createCodeBlockCommand,
insertHrCommand,
Expand All @@ -8,7 +8,6 @@ import {
} from "@milkdown/preset-commonmark";
import {NgMilkdownSlash} from "../../../../projects/ng-milkdown/src/lib/directive/ng-milkdown-slash.directive";
import {Ctx} from "@milkdown/ctx";
import {Is, when} from 'conditio';

@Component({
selector: 'slash',
Expand All @@ -22,49 +21,49 @@ export class Slash extends NgMilkdownSlash {
{
label: 'Heading 1',
icon: 'looks_one',
command: wrapInHeadingCommand.key,
payload: 1,
},
{
label: 'Heading 2',
icon: 'looks_two',
command: wrapInHeadingCommand.key,
payload: 2,
},
{
label: 'Heading 3',
icon: 'looks_3',
command: wrapInHeadingCommand.key,
payload: 3,
},
{
label: 'Code Block',
icon: 'data_object',
icon: 'code_blocks',
command: createCodeBlockCommand.key,
},
{
label: 'Quote Block',
icon: 'format_quote',
command: wrapInBlockquoteCommand.key,
},
{
label: 'Divider',
icon: 'horizontal_rule',
command: insertHrCommand.key,
payload: {mode: 'horizontal'},
}
];

override get onPick(): (ctx: Ctx) => void {
const callCommand = (command: CmdKey<any>, payload: any = null) => {
return (ctx: Ctx) => {
this.removeSlash(ctx);
ctx.get(commandsCtx).call(command, payload);
}
}
const command = when(this.selected)(
Is(0, () => callCommand(wrapInHeadingCommand.key, 1)),
Is(1, () => callCommand(wrapInHeadingCommand.key, 2)),
Is(2, () => callCommand(wrapInHeadingCommand.key, 3)),
Is(3, () => callCommand(createCodeBlockCommand.key)),
Is(4, () => callCommand(wrapInBlockquoteCommand.key)),
Is(5, () => callCommand(insertHrCommand.key, {mode: 'horizontal'})),
)
const {command, payload} = this.list[this.selected]
setTimeout(() => {
this.action(ctx => {
ctx.get(editorViewCtx).focus();
})
})
return command;
return (ctx: Ctx) => {
this.removeSlash(ctx);
ctx.get(commandsCtx).call(command, payload);
}
}
}
153 changes: 99 additions & 54 deletions src/app/components/tool-bar.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,47 +18,23 @@ import {
import {callCommand} from '@milkdown/utils';
import {insertTableCommand, toggleStrikethroughCommand} from "@milkdown/preset-gfm";
import {insertDiagramCommand} from "@milkdown/plugin-diagram";

@Component({
selector: 'nav-bar-button',
standalone: true,
template: `
<div class="flex h-10 w-10 cursor-pointer items-center justify-center rounded hover:bg-gray-100"
(mousedown)="onMouseDown($event)">
<span class="material-symbols-outlined !text-base">
<ng-content/>
</span>
</div>
`,
})
export class NavBarBtnComponent {
@Output() onClick: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();
onMouseDown(e: MouseEvent){
e.preventDefault();
this.onClick.emit(e);
}
}
import {CmdKey} from "@milkdown/core";

@Component({
selector: 'tool-bar',
template: `
<div class="absolute top-0 h-10 w-full border-b border-nord4 dark:divide-gray-600 dark:border-gray-600">
<div class="prose mx-auto flex">
<nav-bar-button (onClick)="call('undo')">undo</nav-bar-button>
<nav-bar-button (onClick)="call('redo')">redo</nav-bar-button>
<nav-bar-button class="hidden-xs" (onClick)="call('wrapInHeading', 1)">looks_one</nav-bar-button>
<nav-bar-button class="hidden-sm" (onClick)="call('wrapInHeading', 2)">looks_two</nav-bar-button>
<nav-bar-button class="hidden-sm" (onClick)="call('wrapInHeading', 3)">looks_3</nav-bar-button>
<nav-bar-button (onClick)="call('toggleStrong')">format_bold</nav-bar-button>
<nav-bar-button (onClick)="call('toggleEmphasis')">format_italic</nav-bar-button>
<nav-bar-button (onClick)="call('toggleStrikethrough')">format_strikethrough</nav-bar-button>
<nav-bar-button class="hidden-xs" (onClick)="call('insertTable')">table</nav-bar-button>
<nav-bar-button (onClick)="call('insertHr')">horizontal_rule</nav-bar-button>
<nav-bar-button class="hidden-sm" (onClick)="call('insertDiagram')">rebase</nav-bar-button>
<nav-bar-button (onClick)="call('wrapInBulletList')">format_list_bulleted</nav-bar-button>
<nav-bar-button (onClick)="call('wrapInOrderedList')">format_list_numbered</nav-bar-button>
<nav-bar-button class="hidden-sm" (onClick)="call('wrapInCodeBlock')">data_object</nav-bar-button>
<nav-bar-button (onClick)="call('wrapInBlockquote')">format_quote</nav-bar-button>
@for (item of navBarItems;track $index) {
<div class="flex h-10 w-10 cursor-pointer items-center justify-center rounded hover:bg-gray-100"
[title]="item.title"
(mousedown)="onMouseDown($event, item.slice, item.payload)"
(touchstart)="onMouseDown($event, item.slice, item.payload)"
[class]="item.className"
>
<span class="material-symbols-outlined !text-base">{{ item.icon }}</span>
</div>
}
</div>
</div>
`,
Expand All @@ -75,9 +51,6 @@ export class NavBarBtnComponent {
}
}
`],
imports: [
NavBarBtnComponent
],
standalone: true
})
export class ToolBarComponent {
Expand All @@ -87,22 +60,94 @@ export class ToolBarComponent {
return actionFactory(this.provider.editor);
}

call(cmd: string, payload?: any) {
const slice = when(cmd)(
Is('undo', undoCommand.key),
Is('redo', redoCommand.key),
Is('toggleStrong', toggleStrongCommand.key),
Is('toggleEmphasis', toggleEmphasisCommand.key),
Is('toggleStrikethrough', toggleStrikethroughCommand.key),
Is('insertTable', insertTableCommand.key),
Is('insertHr', insertHrCommand.key),
Is('insertDiagram', insertDiagramCommand.key),
Is('wrapInBulletList', wrapInBulletListCommand.key),
Is('wrapInOrderedList', wrapInOrderedListCommand.key),
Is('wrapInHeading', wrapInHeadingCommand.key),
Is('wrapInCodeBlock', createCodeBlockCommand.key),
Is('wrapInBlockquote', wrapInBlockquoteCommand.key),
);
navBarItems = [
{
title: 'Undo',
icon: 'undo',
slice: undoCommand.key,
},
{
title: 'Redo',
icon: 'redo',
slice: redoCommand.key,
},
{
title: 'Heading 1',
icon: 'looks_one',
slice: wrapInHeadingCommand.key,
payload: 1,
className: ['hidden-xs']
},
{
title: 'Heading 2',
icon: 'looks_two',
slice: wrapInHeadingCommand.key,
payload: 2,
className: ['hidden-sm']
},
{
title: 'Heading 3',
icon: 'looks_3',
slice: wrapInHeadingCommand.key,
payload: 3,
className: ['hidden-sm']
},
{
title: 'Bold',
icon: 'format_bold',
slice: toggleStrongCommand.key,
},
{
title: 'Italic',
icon: 'format_italic',
slice: toggleEmphasisCommand.key,
},
{
title: 'Strikethrough',
icon: 'format_strikethrough',
slice: toggleStrikethroughCommand.key,
},
{
title: 'Table',
icon: 'table',
slice: insertTableCommand.key,
},
{
title: 'Divider',
icon: 'horizontal_rule',
slice: insertHrCommand.key,
payload: {mode: 'horizontal'},
},
{
title: 'Diagram',
icon: 'rebase',
slice: insertDiagramCommand.key,
className: ['hidden-sm']
},
{
title: 'Bullet List',
icon: 'format_list_bulleted',
slice: wrapInBulletListCommand.key,
},
{
title: 'Ordered List',
icon: 'format_list_numbered',
slice: wrapInOrderedListCommand.key,
},
{
title: 'Code Block',
icon: 'code_blocks',
slice: createCodeBlockCommand.key,
},
{
title: 'Quote Block',
icon: 'format_quote',
slice: wrapInBlockquoteCommand.key,
}
]

onMouseDown(e: MouseEvent | TouchEvent, slice: CmdKey<any>, payload?: any) {
e.preventDefault();
this.action(callCommand(slice, payload));
}
}
54 changes: 14 additions & 40 deletions src/app/components/tooltip/tooltip.component.html
Original file line number Diff line number Diff line change
@@ -1,40 +1,14 @@
<div class="flex w-64">
<button
title="Undo"
class="flex-1 text-gray-600 text-xs bg-slate-200 px-2 py-1 hover:bg-slate-300 border border-r-2 border-r-blue-50 border-b-blue-50 hover:text-gray-900 whitespace-nowrap"
(mousedown)="undo($event)">
<span class="material-symbols-outlined">undo</span>
</button>
<button
title="Redo"
class="flex-1 text-gray-600 text-xs bg-slate-200 px-2 py-1 hover:bg-slate-300 border border-b-blue-50 hover:text-gray-900 whitespace-nowrap"
(mousedown)="redo($event)">
<span class="material-symbols-outlined">redo</span>
</button>
</div>
<div class="flex-1 flex w-64">
<button
title="Bold"
class="text-gray-600 text-xs bg-slate-200 px-2 py-1 hover:bg-slate-300 border border-b-blue-50 hover:text-gray-900"
(mousedown)="setBold($event)">
<span class="material-symbols-outlined">format_bold</span>
</button>
<button
title="Italic"
class="flex-1 text-gray-600 text-xs bg-slate-200 px-2 py-1 hover:bg-slate-300 border border-b-blue-50 hover:text-gray-900"
(mousedown)="setItalic($event)">
<span class="material-symbols-outlined">format_italic</span>
</button>
<button
title="Underline"
class="flex-1 text-gray-600 text-xs bg-slate-200 px-2 py-1 hover:bg-slate-300 border border-b-blue-50 hover:text-gray-900"
(mousedown)="strikethrough($event)">
<span class="material-symbols-outlined">format_strikethrough</span>
</button>
<button
title="Quote"
class="flex-1 text-gray-600 text-xs bg-slate-200 px-2 py-1 hover:bg-slate-300 border border-b-blue-50 hover:text-gray-900"
(mousedown)="quote($event)">
<span class="material-symbols-outlined">format_quote</span>
</button>
</div>
@for(line of buttons;track line){
<div class="flex-1 flex w-64">
@for(button of line;track button){
<button
[title]="button.title"
class="flex-1 text-gray-600 text-xs bg-slate-200 px-2 py-1 hover:bg-slate-300 border border-b-blue-50 hover:text-gray-900"
(mousedown)="mousedown($event, button.command)"
(touchstart)="mousedown($event, button.command)"
>
<span class="material-symbols-outlined">{{ button.icon }}</span>
</button>
}
</div>
}
Loading

0 comments on commit 7cc3d66

Please sign in to comment.