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';