浏览代码

feat: 新增 路由 弹窗页面、组件

YuJing 1 月之前
父节点
当前提交
a88dd378fa

+ 1 - 0
commons/basic/Index.ets

@@ -75,6 +75,7 @@ export * from '@mumu/crop'
 
 export * from './src/main/ets/models'
 
+export { YTDiaLogComp } from './src/main/ets/components/generalComp/YTDiaLogComp'
 
 
 

+ 103 - 0
commons/basic/src/main/ets/components/generalComp/YTDiaLogComp.ets

@@ -0,0 +1,103 @@
+import { YTDiaLogModel } from 'feature/src/main/ets/model/YTDiaLogModel'
+import { yTRouter } from '../../utils/YTRouter'
+
+@ComponentV2
+export struct YTDiaLogComp {
+  @Local _offset: Length = '0%'
+  @Local _opacity: number = 0
+
+  // 弹窗的位置: 底部,中间。(均有对应的动画)
+  @Require @Param Align: YTDiaLogModel = YTDiaLogModel.Bottom
+  // 是否返回
+  @Require @Param isBack: boolean
+  // 弹窗的内容
+  @BuilderParam _content: () => void
+  // 重新返回方法
+  @Event _onPop: () => void = () => {
+    yTRouter.pop('', false)
+  }
+
+  @Monitor('isBack')
+  fatherIsBack(){
+    setTimeout(() => {
+      this._onBackPress()
+    }, 0)
+  }
+
+  private _onBackPress(ans?: string | boolean) {
+    animateToImmediately({
+      duration: 300
+    }, () => {
+      if(this.Align === YTDiaLogModel.Bottom) {
+        this._offset = '0%'
+      } else {
+        this._opacity = 0
+      }
+    })
+    setTimeout(() => {
+      this._onPop()
+    }, 250)
+    return true
+  }
+
+  private _onAppear(){
+    animateToImmediately({
+      duration: 350
+    }, () => {
+      this._offset = '-100%'
+      this._opacity = 1
+    })
+  }
+
+  private getAlign(): FlexAlign{
+    if(this.Align === YTDiaLogModel.Center) return FlexAlign.Center
+    else if (this.Align === YTDiaLogModel.Bottom) return FlexAlign.End
+		return FlexAlign.Center
+	}
+
+  aboutToAppear(): void {
+    if(this.Align === YTDiaLogModel.Center) this._offset = '-100%'
+  }
+
+  build() {
+    NavDestination() {
+      Column() {
+        Column()
+          .height('50%')
+          .width("100%")
+          .backgroundColor('rgba(0, 0, 0, 0.5)')
+
+        Column(){
+          Column(){
+            if(this._content) {
+              this._content()
+            }
+          }
+          .onClick(() => {})
+          .scale(this.Align === YTDiaLogModel.Center ? { x: this._opacity, y: this._opacity, centerX:'50%', centerY:'75%' } : null)
+        }
+        .width('100%')
+        .height('50%')
+        .justifyContent(this.getAlign())
+        .backgroundColor('rgba(0, 0, 0, 0.5)')
+        .alignItems(HorizontalAlign.Center)
+        .onClick(() => {
+          this._onBackPress()
+        })
+      }
+      .height('200%')
+      .width("100%")
+      .offset({
+        y: this._offset
+      })
+      .opacity(this._opacity)
+      .onAppear(() => { this._onAppear() })
+    }
+    .hideTitleBar(true)
+    .mode(NavDestinationMode.DIALOG)
+    .systemTransition(NavigationSystemTransitionType.NONE)
+    .onBackPressed(() => {
+      return this._onBackPress()
+    })
+  }
+}

+ 26 - 0
commons/basic/src/main/ets/models/YTDiaLogModel.ets

@@ -0,0 +1,26 @@
+import { BasicType } from ".";
+
+
+export enum YTDiaLogModel {
+  Center,
+  Bottom,
+}
+
+export enum DiaLogPageEnum{
+  // 日期选择
+  DatePicker,
+  // 数字输入
+  NumBerInput,
+  // 文本输入
+  TextInput,
+  // 对话框 - 确认
+  Confirm,
+  // 底部菜单
+  BottomMenu,
+}
+
+export interface DiaLogParam{
+  pageEnum: DiaLogPageEnum,
+  param?: BasicType,
+  params?: Array<BasicType>
+}

+ 10 - 0
commons/basic/src/main/ets/utils/YTRouter.ets

@@ -1,5 +1,6 @@
 import { IBestToast } from '@ibestservices/ibest-ui'
 import { DelPhotoParam } from '../models'
+import { DiaLogParam } from '../models/YTDiaLogModel'
 
 class YTRouter extends NavPathStack {
   private static declare instance: YTRouter
@@ -72,6 +73,15 @@ class YTRouter extends NavPathStack {
   routerBack() {
     yTRouter.pop()
   }
+
+
+  router2NaviDiaLog(param: DiaLogParam, back?: Callback<PopInfo>){
+    yTRouter.pushPathByName('YTNaviDiaLog', param, back, false)
+  }
+
+  getNaviDiaLogParam(){
+    return yTRouter.getParamByName('YTNaviDiaLog').pop() as DiaLogParam
+  }
 }
 
 export const yTRouter = YTRouter.getInstance()

+ 63 - 0
features/feature/src/main/ets/pages/YTNaviDiaLog.ets

@@ -0,0 +1,63 @@
+import { BasicType, yTRouter } from 'basic'
+import { YTDiaLogComp } from 'basic/src/main/ets/components/generalComp/YTDiaLogComp'
+import { DiaLogParam, YTDiaLogModel } from 'basic/src/main/ets/models/YTDiaLogModel'
+
+@ComponentV2
+struct YTNaviDiaLog {
+  @Local param: DiaLogParam = {} as DiaLogParam
+  @Local isPop: boolean = false
+  @Local routerAns: string = ''
+
+  _onBackPress = () => {
+    yTRouter.pop(this.routerAns, false)
+  }
+
+  onBack(){
+    this.isPop = !this.isPop
+  }
+
+  aboutToAppear(): void {
+    this.param = yTRouter.getNaviDiaLogParam()
+  }
+
+  build() {
+    YTDiaLogComp({ Align: YTDiaLogModel.Bottom, _onPop: this._onBackPress, isBack: this.isPop }){
+      this.BottomMenu()
+    }
+  }
+
+  // 底部菜单
+  @Builder BottomMenu() {
+    Column(){
+      ForEach(this.param.params, (item: BasicType, index) => {
+        Row(){
+          Text(item.text)
+            .fontSize(16)
+            .textAlign(TextAlign.Center)
+        }
+        .width("100%")
+        .alignItems(VerticalAlign.Center)
+        .justifyContent(FlexAlign.Center)
+        .padding({ top: 24, bottom: 24 })
+        .onClick(() => {
+          this.routerAns = item.message ?? item.text ?? `${index}`
+          this.onBack()
+        })
+
+        Divider().width("80%").height(1).backgroundColor('#000000F2')
+      })
+    }
+    .width("100%")
+    .padding({ bottom: 30 })
+    .backgroundColor(Color.White)
+    .justifyContent(FlexAlign.Center)
+    .alignItems(HorizontalAlign.Center)
+    .borderRadius({ topLeft: 8, topRight: 8 })
+  }
+}
+
+@Builder
+function YTNaviDiaLogBuilder() {
+  YTNaviDiaLog()
+}
+

+ 5 - 1
features/feature/src/main/resources/base/profile/router_map.json

@@ -1,5 +1,9 @@
 {
   "routerMap": [
-
+    {
+      "name": "YTNaviDiaLog",
+      "pageSourceFile": "src/main/ets/pages/YTNaviDiaLog.ets",
+      "buildFunction": "YTNaviDiaLogBuilder"
+    }
   ]
 }