From 92ce1b7f66aff187bfcf28fd83aac4fedcc97658 Mon Sep 17 00:00:00 2001 From: Haoxin Yang <1810849666@qq.com> Date: Wed, 3 Jul 2024 10:49:25 +0800 Subject: [PATCH] feat: in place editor --- index.js | 39 +++++++++++++++ src/editable/editable.component.html | 35 ++++++++++++++ src/editable/editable.component.scss | 22 +++++++++ src/editable/editable.component.ts | 72 ++++++++++++++++++++++++++++ src/editable/editable.directive.ts | 13 +++++ src/editable/editable.module.ts | 21 ++++++++ src/editable/editable.type.ts | 4 ++ src/editable/index.ts | 3 ++ src/index.ts | 1 + 9 files changed, 210 insertions(+) create mode 100644 index.js create mode 100644 src/editable/editable.component.html create mode 100644 src/editable/editable.component.scss create mode 100644 src/editable/editable.component.ts create mode 100644 src/editable/editable.directive.ts create mode 100644 src/editable/editable.module.ts create mode 100644 src/editable/editable.type.ts create mode 100644 src/editable/index.ts diff --git a/index.js b/index.js new file mode 100644 index 000000000..5bbda8ffd --- /dev/null +++ b/index.js @@ -0,0 +1,39 @@ +class Calculator { + expr; + operator; + + constructor(expr) { + this.expr = expr; + + this.operator = ['+', '-', '*', '/'].find(operator => + expr.includes(operator), + ); + } + + count() { + const [num1, num2] = this.expr.split(this.operator).map(v => parseInt(v)); + + switch (this.operator) { + case '+': { + return num1 + num2; + } + case '-': { + return num1 - num2; + } + case '*': { + return num1 * num2; + } + case '/': { + return num1 / num2; + } + } + } + + get result() { + return this.count(); + } +} + +const calculator = new Calculator('1*8'); + +console.log(calculator.result); diff --git a/src/editable/editable.component.html b/src/editable/editable.component.html new file mode 100644 index 000000000..0cb1068ce --- /dev/null +++ b/src/editable/editable.component.html @@ -0,0 +1,35 @@ +
+
+ + +
+ +
+ + + + +
+
+
diff --git a/src/editable/editable.component.scss b/src/editable/editable.component.scss new file mode 100644 index 000000000..39cbd5323 --- /dev/null +++ b/src/editable/editable.component.scss @@ -0,0 +1,22 @@ +@import '../theme/var'; +@import '../theme/mixin'; + +.aui-editable { + .aui-button--text { + color: use-rgb(main-text); + + &:first-of-type { + margin-left: 8px; + } + + &:hover { + color: use-rgb(primary); + } + } + + &__view-container, + &__editor-container { + display: flex; + align-items: center; + } +} diff --git a/src/editable/editable.component.ts b/src/editable/editable.component.ts new file mode 100644 index 000000000..4e242ed42 --- /dev/null +++ b/src/editable/editable.component.ts @@ -0,0 +1,72 @@ +import { AsyncPipe, NgFor, NgIf, NgTemplateOutlet } from '@angular/common'; +import { + ChangeDetectionStrategy, + Component, + ContentChild, + EventEmitter, + Output, + TemplateRef, + effect, + signal, +} from '@angular/core'; + +import { ButtonModule } from '../button'; +import { IconComponent } from '../icon'; +import { buildBem } from '../internal/utils'; + +import { + EditableEditorDirective, + EditableViewerDirective, +} from './editable.directive'; +import { EditableMode } from './editable.type'; + +const bem = buildBem('aui-editable'); + +@Component({ + selector: 'aui-editable', + templateUrl: 'editable.component.html', + styleUrls: ['editable.component.scss'], + standalone: true, + imports: [ + NgIf, + NgFor, + AsyncPipe, + NgTemplateOutlet, + IconComponent, + ButtonModule, + ], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class EditableComponent { + @Output() save: EventEmitter = new EventEmitter(); + @Output() cancel: EventEmitter = new EventEmitter(); + @Output() modeChange: EventEmitter = + new EventEmitter(); + + @ContentChild(EditableViewerDirective, { read: TemplateRef }) + viewer: TemplateRef; + + @ContentChild(EditableEditorDirective, { read: TemplateRef }) + editor: TemplateRef; + + EditableMode = EditableMode; + bem = bem; + + $$mode = signal(EditableMode.View); + + constructor() { + effect(() => { + this.modeChange.emit(this.$$mode()); + }); + } + + saveEdit() { + this.$$mode.set(EditableMode.View); + this.save.emit(); + } + + cancelEdit() { + this.$$mode.set(EditableMode.View); + this.cancel.emit(); + } +} diff --git a/src/editable/editable.directive.ts b/src/editable/editable.directive.ts new file mode 100644 index 000000000..67209167b --- /dev/null +++ b/src/editable/editable.directive.ts @@ -0,0 +1,13 @@ +import { Directive } from '@angular/core'; + +@Directive({ + selector: '*[auiEditableViewer]', + standalone: true, +}) +export class EditableViewerDirective {} + +@Directive({ + selector: '*[auiEditableEditor]', + standalone: true, +}) +export class EditableEditorDirective {} diff --git a/src/editable/editable.module.ts b/src/editable/editable.module.ts new file mode 100644 index 000000000..00078723b --- /dev/null +++ b/src/editable/editable.module.ts @@ -0,0 +1,21 @@ +import { NgModule } from '@angular/core'; + +import { EditableComponent } from './editable.component'; +import { + EditableEditorDirective, + EditableViewerDirective, +} from './editable.directive'; + +@NgModule({ + imports: [ + EditableComponent, + EditableViewerDirective, + EditableEditorDirective, + ], + exports: [ + EditableComponent, + EditableViewerDirective, + EditableEditorDirective, + ], +}) +export class EditableModule {} diff --git a/src/editable/editable.type.ts b/src/editable/editable.type.ts new file mode 100644 index 000000000..af0a49220 --- /dev/null +++ b/src/editable/editable.type.ts @@ -0,0 +1,4 @@ +export enum EditableMode { + View = 'view', + Edit = 'edit', +} diff --git a/src/editable/index.ts b/src/editable/index.ts new file mode 100644 index 000000000..ad70f1d20 --- /dev/null +++ b/src/editable/index.ts @@ -0,0 +1,3 @@ +export * from './editable.component'; +export * from './editable.directive'; +export * from './editable.module'; diff --git a/src/index.ts b/src/index.ts index dece82d2d..32302a782 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,6 +11,7 @@ export * from './date-picker'; export * from './dialog'; export * from './drawer'; export * from './dropdown'; +export * from './editable'; export * from './form'; export * from './i18n'; export * from './icon';