已合并
test(dialog-api26): DialogStyle 与 BaseOptions 等接口覆盖;Co-authored-by: Agent #42493
test(dialog-api26): DialogStyle 与 BaseOptions 等接口覆盖;Co-authored-by: Agent #42493
已合并
Dongwei创建于 7月30日
94 个文件变更+11387-0
@@ -24,6 +24,7 @@ group("ActsAceEtsModuleDialogTest") {
24 # "ace_ets_module_dialog_api18:ActsAceEtsModuleDialogApi18Test",24 # "ace_ets_module_dialog_api18:ActsAceEtsModuleDialogApi18Test",
25 # "ace_ets_module_dialog_api19:ActsAceEtsModuleDialogApi19Test",25 # "ace_ets_module_dialog_api19:ActsAceEtsModuleDialogApi19Test",
26 # "ace_ets_module_dialog_api20:ActsAceEtsModuleDialogApi20Test",26 # "ace_ets_module_dialog_api20:ActsAceEtsModuleDialogApi20Test",
27+ "ace_ets_module_dialog_api26:ActsAceEtsModuleDialogApi26Test",
27 "ace_ets_module_dialog_button:ActsAceEtsModuleDialogButtonTest",28 "ace_ets_module_dialog_button:ActsAceEtsModuleDialogButtonTest",
28 "ace_ets_module_dialog_toggle:ActsAceEtsModuleDialogToggleTest",29 "ace_ets_module_dialog_toggle:ActsAceEtsModuleDialogToggleTest",
29 "ace_ets_module_dialog_radio:ActsAceEtsModuleDialogRadioTest",30 "ace_ets_module_dialog_radio:ActsAceEtsModuleDialogRadioTest",
@@ -53,6 +54,7 @@ group("ActsAceEtsModuleDialogTest") {
53 # "ace_ets_module_dialog_api18:ActsAceEtsModuleDialogApi18Test",54 # "ace_ets_module_dialog_api18:ActsAceEtsModuleDialogApi18Test",
54 # "ace_ets_module_dialog_api19:ActsAceEtsModuleDialogApi19Test",55 # "ace_ets_module_dialog_api19:ActsAceEtsModuleDialogApi19Test",
55 # "ace_ets_module_dialog_api20:ActsAceEtsModuleDialogApi20Test",56 # "ace_ets_module_dialog_api20:ActsAceEtsModuleDialogApi20Test",
57+ "ace_ets_module_dialog_api26:ActsAceEtsModuleDialogApi26Test",
56 "ace_ets_module_dialog_api23_static:ActsAceEtsModuleDialogApi23StaticTest",58 "ace_ets_module_dialog_api23_static:ActsAceEtsModuleDialogApi23StaticTest",
57 "ace_ets_module_dialog_nowear_api11:ActsAceEtsModuleDialogNoWearApi11Test",59 "ace_ets_module_dialog_nowear_api11:ActsAceEtsModuleDialogNoWearApi11Test",
58 "ace_ets_module_dialog_nowear_api12:ActsAceEtsModuleDialogNoWearApi12Test",60 "ace_ets_module_dialog_nowear_api12:ActsAceEtsModuleDialogNoWearApi12Test",
@@ -0,0 +1,26 @@
1+/*
2+ * Copyright (c) 2025 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+{
17+ "app": {
18+ "bundleName": "com.arkui.ace.dialog.api26",
19+ "vendor": "huawei",
20+ "versionCode": 1000000,
21+ "versionName": "1.0.0",
22+ "icon": "$media:app_icon",
23+ "label": "$string:app_name",
24+ "description": "$string:description_application"
25+ }
26+}
@@ -0,0 +1,8 @@
1+{
2+ "string":[
3+ {
4+ "name":"app_name",
5+ "value":"DialogApi26"
6+ }
7+ ]
8+}
@@ -0,0 +1,32 @@
1+# Copyright (c) 2025 Huawei Device Co., Ltd.
2+# Licensed under the Apache License, Version 2.0 (the "License");
3+# you may not use this file except in compliance with the License.
4+# You may obtain a copy of the License at
5+#
6+# http://www.apache.org/licenses/LICENSE-2.0
7+#
8+# Unless required by applicable law or agreed to in writing, software
9+# distributed under the License is distributed on an "AS IS" BASIS,
10+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+# See the License for the specific language governing permissions and
12+# limitations under the License.
13+ 
14+import("//test/xts/tools/build/suite.gni")
15+ 
16+ohos_app_assist_suite("ActsAceEtsModuleDialogApi26TestMain") {
17+ testonly = true
18+ certificate_profile = "./signature/openharmony_sx.p7b"
19+ hap_name = "ActsAceEtsModuleDialogApi26TestMain"
20+ part_name = "ace_engine"
21+ subsystem_name = "arkui"
22+}
23+ 
24+ohos_js_app_suite("ActsAceEtsModuleDialogApi26Test") {
25+ test_hap = true
26+ testonly = true
27+ certificate_profile = "./signature/openharmony_sx.p7b"
28+ hap_name = "ActsAceEtsModuleDialogApi26Test"
29+ part_name = "ace_engine"
30+ subsystem_name = "arkui"
31+ deps = [ ":ActsAceEtsModuleDialogApi26TestMain" ]
32+}
@@ -0,0 +1,27 @@
1+{
2+ "description": "Configuration for hjunit demo Tests",
3+ "driver": {
4+ "type": "OHJSUnitTest",
5+ "test-timeout": "180000",
6+ "bundle-name": "com.arkui.ace.dialog.api26",
7+ "module-name": "entry_test",
8+ "shell-timeout": "600000",
9+ "testcase-timeout": "180000"
10+ },
11+ "kits": [{
12+ "test-file-name": [
13+ "ActsAceEtsModuleDialogApi26Test.hap",
14+ "ActsAceEtsModuleDialogApi26TestMain.hap"
15+ ],
16+ "type": "AppInstallKit",
17+ "cleanup-apps": true
18+ },{
19+ "type": "ShellKit",
20+ "run-command": [
21+ "power-shell wakeup",
22+ "uinput -T -m 300 2700 280 200",
23+ "power-shell setmode 602",
24+ "power-shell timeout -o 864000000"
25+ ]
26+ }]
27+}
@@ -0,0 +1,45 @@
1+/*
2+ * Copyright (c) 2025 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+{
17+ "app": {
18+ "signingConfigs": [
19+ 
20+ ],
21+ "products": [
22+ {
23+ "name": "default",
24+ "signingConfig": "default",
25+ "compileSdkVersion": "26.0.0",
26+ "compatibleSdkVersion": "26.0.0",
27+ "runtimeOS": "OpenHarmony"
28+ }
29+ ]
30+ },
31+ "modules": [
32+ {
33+ "name": "entry",
34+ "srcPath": "./entry",
35+ "targets": [
36+ {
37+ "name": "default",
38+ "applyToProducts": [
39+ "default"
40+ ]
41+ }
42+ ]
43+ }
44+ ]
45+}
@@ -0,0 +1,6 @@
1+/node_modules
2+/oh_modules
3+/.preview
4+/build
5+/.cxx
6+/.test
@@ -0,0 +1,27 @@
1+/*
2+ * Copyright (c) 2025 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+{
17+ "apiType": 'stageMode',
18+ "targets": [
19+ {
20+ "name": "default",
21+ "runtimeOS": "OpenHarmony"
22+ },
23+ {
24+ "name": "ohosTest",
25+ }
26+ ]
27+}
@@ -0,0 +1,17 @@
1+/*
2+ * Copyright (c) 2025 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
17+export { hapTasks } from '@ohos/hvigor-ohos-plugin';
@@ -0,0 +1,24 @@
1+/**
2+ * Copyright (c) 2025 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+{
17+ "license": "",
18+ "author": "",
19+ "name": "entry",
20+ "description": "Please describe the basic information.",
21+ "main": "",
22+ "version": "1.0.0",
23+ "dependencies": {}
24+}
@@ -0,0 +1,23 @@
1+/**
2+ * Copyright (c) 2025 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+import AbilityStage from "@ohos.app.ability.AbilityStage"
16+ 
17+export default class MyAbilityStage extends AbilityStage {
18+ onCreate() {
19+ console.log("[Demo] MyAbilityStage onCreate")
20+ globalThis.stageOnCreateRun = 1;
21+ globalThis.stageContext = this.context;
22+ }
23+}
@@ -0,0 +1,73 @@
1+/**
2+ * Copyright (c) 2025 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+import screen from '@ohos.screen';
16+import { BusinessError } from '@ohos.base';
17+ 
18+export class RectValue {
19+ left: number = 0;
20+ top: number = 0;
21+ right: number = 0;
22+ bottom: number = 0;
23+}
24+ 
25+export default class CommonFunc {
26+ static rect_left: number;
27+ static rect_top: number;
28+ static rect_right: number;
29+ static rect_bottom: number;
30+ static rect_value: RectValue;
31+ 
32+ static sleep(time: number){
33+ return new Promise<string>((resolve,reject)=>{
34+ setTimeout(()=>{
35+ resolve("ok")
36+ },time)
37+ }).then(()=>{
38+ console.info(`sleep ${time} over...`)
39+ })
40+ }
41+ 
42+ static getComponentRect(key: string) {
43+ let strJson = getInspectorByKey(key);
44+ let obj: Record<string, Object> = JSON.parse(strJson);
45+ console.info("[getInspectorByKey] current component obj is: " + JSON.stringify(obj));
46+ let rectInfo: string[] = JSON.parse('[' + obj.$rect + ']');
47+ CommonFunc.rect_left = JSON.parse('[' + rectInfo[0] + ']')[0];
48+ CommonFunc.rect_top = JSON.parse('[' + rectInfo[0] + ']')[1];
49+ CommonFunc.rect_right = JSON.parse('[' + rectInfo[1] + ']')[0];
50+ CommonFunc.rect_bottom = JSON.parse('[' + rectInfo[1] + ']')[1];
51+ CommonFunc.rect_value = {
52+ "left": CommonFunc.rect_left,
53+ "top": CommonFunc.rect_top,
54+ "right": CommonFunc.rect_right,
55+ "bottom": CommonFunc.rect_bottom
56+ };
57+ console.info(JSON.stringify(CommonFunc.rect_value));
58+ return CommonFunc.rect_value;
59+ }
60+ 
61+ static setScreenOrientation(orientation: number) {
62+ screen.getAllScreens().then(data => {
63+ console.log('Succeeded in getting all screens. Data:'+ JSON.stringify(data));
64+ return data[0];
65+ }).then(screenClass => {
66+ return screenClass.setOrientation(orientation);
67+ }).then(() => {
68+ console.log('Succeeded in setting the vertical orientation.');
69+ }).catch((err: BusinessError) => {
70+ console.error('Failed to set the vertical orientation. Cause: ' + err.toString());
71+ });
72+ }
73+}
@@ -0,0 +1,53 @@
1+/**
2+ * Copyright (c) 2025 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+ 
17+const TAG = 'ets_apiLack_add';
18+ 
19+/**
20+ * Basic log class
21+ */
22+export default class Log {
23+ 
24+ /**
25+ * print info level log
26+ *
27+ * @param {string} tag - Page or class tag
28+ * @param {string} log - Log needs to be printed
29+ */
30+ static showInfo(tag, log) {
31+ console.info(`${TAG} tag: ${tag} --> ${log}`);
32+ }
33+ 
34+ /**
35+ * print debug level log
36+ *
37+ * @param {string} tag - Page or class tag
38+ * @param {string} log - Log needs to be printed
39+ */
40+ static showDebug(tag, log) {
41+ console.debug(`${TAG} tag: ${tag} --> ${log}`);
42+ }
43+ 
44+ /**
45+ * print error level log
46+ *
47+ * @param {string} tag - Page or class tag
48+ * @param {string} log - Log needs to be printed
49+ */
50+ static showError(tag, log) {
51+ console.error(`${TAG} tag: ${tag} --> ${log}`);
52+ }
53+}
@@ -0,0 +1,54 @@
1+/**
2+ * Copyright (c) 2025 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+export type Callback = (message: ESObject) => void
16+ 
17+export class MessageManager {
18+ callback?: Callback = undefined
19+ callbacks: Map<string, Callback> = new Map()
20+ 
21+ constructor() {
22+ 
23+ }
24+ 
25+ registerCallback(callback: Callback, type?: string) {
26+ if (type == undefined) {
27+ console.error('registerCallback callback set')
28+ this.callback = callback
29+ return
30+ }
31+ this.callbacks.set(type, callback)
32+ }
33+ 
34+ notify(message: ESObject, type?: string) {
35+ if (type == undefined) {
36+ if (this.callback !== undefined) {
37+ this.callback(message)
38+ }
39+ return
40+ }
41+ 
42+ let tmpCallback: Callback | undefined = this.callbacks.get(type)
43+ if (tmpCallback === undefined) {
44+ console.error('callbacks has no callback for type ' + type)
45+ return
46+ }
47+ tmpCallback(message)
48+ }
49+ 
50+ clear() {
51+ this.callbacks.clear()
52+ this.callback = undefined
53+ }
54+}
@@ -0,0 +1,21 @@
1+/**
2+ * Copyright (c) 2025 iSoftStone Information Technology (Group) Co.,Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+export default class RectValue {
17+ left: number = 0;
18+ top: number = 0;
19+ right: number = 0;
20+ bottom: number = 0;
21+ }
@@ -0,0 +1,126 @@
1+/**
2+ * Copyright (c) 2025 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+import RectValue from './Rect';
16+ 
17+export default class Utils {
18+ static rect_left: number;
19+ static rect_top: number;
20+ static rect_right: number;
21+ static rect_bottom: number;
22+ static rect_value: RectValue;
23+ 
24+ static getComponentRect(key: string) {
25+ let strJson: string = getInspectorByKey(key);
26+ console.info("[getInspectorByKey] current component obj is: " + JSON.stringify(JSON.parse(strJson)));
27+ console.info('[getInspectorByKey] rectInfo is: ' + JSON.parse('[' + JSON.parse(strJson).$rect + ']'));
28+ Utils.rect_left = JSON.parse('[' + JSON.parse('[' + JSON.parse(strJson).$rect + ']')[0] + ']')[0]
29+ Utils.rect_top = JSON.parse('[' + JSON.parse('[' + JSON.parse(strJson).$rect + ']')[0] + ']')[1]
30+ Utils.rect_right = JSON.parse('[' + JSON.parse('[' + JSON.parse(strJson).$rect + ']')[1] + ']')[0]
31+ Utils.rect_bottom = JSON.parse('[' + JSON.parse('[' + JSON.parse(strJson).$rect + ']')[1] + ']')[1]
32+ return Utils.rect_value = {
33+ left: Utils.rect_left, top: Utils.rect_top, right: Utils.rect_right, bottom: Utils.rect_bottom
34+ }
35+ }
36+ 
37+ static sleep(time: number) {
38+ return new Promise((resolve: (value: string) => void) => {
39+ setTimeout(() => {
40+ resolve('ok')
41+ }, time)
42+ }).then(() => {
43+ console.info(`sleep ${time} over...`)
44+ })
45+ }
46+ 
47+ 
48+ static async drag(downX: number, downY: number, upX: number, upY: number, steps: number) {
49+ console.info('start to drag')
50+ let xStep: number;
51+ let yStep: number;
52+ let swipeSteps: number;
53+ let ret: boolean;
54+ xStep = 0;
55+ yStep = 0;
56+ ret = false;
57+ swipeSteps = steps;
58+ if (swipeSteps == 0) {
59+ swipeSteps = 1;
60+ }
61+ xStep = (upX - downX) / swipeSteps;
62+ yStep = (upY - downY) / swipeSteps;
63+ console.info('move step is: ' + 'xStep: ' + xStep + ' yStep: ' + yStep)
64+ let downPoint: TouchObject = {
65+ id: 1,
66+ x: downX,
67+ y: downY,
68+ displayX: downX,
69+ displayY: downY,
70+ windowX: downX,
71+ windowY: downY,
72+ screenX: downX,
73+ screenY: downY,
74+ type: TouchType.Down
75+ }
76+ console.info('down touch started: ' + JSON.stringify(downPoint))
77+ sendTouchEvent(downPoint);
78+ console.info('start to move')
79+ if (true) {
80+ Utils.sleep(500)
81+ }
82+ for (let i = 1; i <= swipeSteps; i++) {
83+ let movePoint: TouchObject = {
84+ id: 1,
85+ x: downX + (xStep * i),
86+ y: downY + (yStep * i),
87+ displayX: downX + (xStep * i),
88+ displayY: downY + (yStep * i),
89+ windowX: downX + (xStep * i),
90+ windowY: downY + (yStep * i),
91+ screenX: downX + (xStep * i),
92+ screenY: downY + (yStep * i),
93+ type: TouchType.Move,
94+ }
95+ console.info('move touch started: ' + JSON.stringify(movePoint))
96+ ret = sendTouchEvent(movePoint)
97+ if (ret == false) {
98+ break;
99+ }
100+ Utils.sleep(5)
101+ }
102+ console.info('start to up')
103+ if (true) {
104+ Utils.sleep(100)
105+ }
106+ let upPoint: TouchObject = {
107+ id: 1,
108+ x: upX,
109+ y: upY,
110+ displayX: upX,
111+ displayY: upY,
112+ windowX: upX,
113+ windowY: upY,
114+ screenX: upX,
115+ screenY: upY,
116+ type: TouchType.Up,
117+ }
118+ console.info('up touch started: ' + JSON.stringify(upPoint))
119+ sendTouchEvent(upPoint)
120+ Utils.sleep(500)
121+ }
122+}
123+ 
124+ 
125+ 
126+ 
@@ -0,0 +1,216 @@
1+/**
2+ * Copyright (c) 2026 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+import {
17+ DialogPresenter,
18+ DialogButtonOrientation,
19+ LevelMode,
20+ dialog,
21+} from '@kit.ArkUI';
22+ 
23+@Entry
24+@Component
25+struct DialogAbnormalOpts {
26+ @State lastAction: string = 'none';
27+ @State lastError: string = 'none';
28+ @State coverFlag: string = 'none';
29+ 
30+ private presenter(): DialogPresenter {
31+ return this.getUIContext().getDialogPresenter();
32+ }
33+ 
34+ private baseOpts(title: string, msg: string, ok: string, act: string): dialog.DialogStyleOptions {
35+ return {
36+ title: title,
37+ message: { content: msg },
38+ buttons: [{
39+ value: ok,
40+ action: () => {
41+ this.lastAction = act;
42+ }
43+ }]
44+ };
45+ }
46+ 
47+ private async runProbe(tag: string, opts: dialog.DialogStyleOptions): Promise<void> {
48+ this.lastError = 'none';
49+ try {
50+ await this.presenter().present(opts);
51+ this.coverFlag = 'ok:' + tag;
52+ } catch (err) {
53+ this.lastError = String(err);
54+ this.coverFlag = 'fail:' + tag;
55+ this.lastAction = 'error';
56+ }
57+ }
58+ 
59+ build() {
60+ Scroll() {
61+ Column({ space: 8 }) {
62+ Text('Dialog optional undefined probe').fontSize(16).fontWeight(FontWeight.Bold)
63+ Text('action=' + this.lastAction).id('abn_action')
64+ Text('error=' + this.lastError).id('abn_error')
65+ Text('cover=' + this.coverFlag).id('abn_cover')
66+ Button('undefined subtitle')
67+ .id('btn_abn_subtitle')
68+ .onClick(async () => {
69+ let opts = this.baseOpts('AbnSubTitle', 'AbnMsg_subtitle', 'AbnOK_subtitle',
70+ 'subtitle_undefined');
71+ opts.subtitle = undefined;
72+ await this.runProbe('subtitle', opts);
73+ })
74+ Button('undefined width')
75+ .id('btn_abn_width')
76+ .onClick(async () => {
77+ let opts = this.baseOpts('AbnWidthTitle', 'AbnMsg_width', 'AbnOK_width', 'width_undefined');
78+ opts.width = undefined;
79+ await this.runProbe('width', opts);
80+ })
81+ Button('undefined height')
82+ .id('btn_abn_height')
83+ .onClick(async () => {
84+ let opts = this.baseOpts('AbnHeightTitle', 'AbnMsg_height', 'AbnOK_height',
85+ 'height_undefined');
86+ opts.height = undefined;
87+ await this.runProbe('height', opts);
88+ })
89+ Button('undefined maskColor')
90+ .id('btn_abn_maskColor')
91+ .onClick(async () => {
92+ let opts = this.baseOpts('AbnMaskTitle', 'AbnMsg_maskColor', 'AbnOK_maskColor',
93+ 'maskColor_undefined');
94+ opts.maskColor = undefined;
95+ await this.runProbe('maskColor', opts);
96+ })
97+ Button('undefined offset')
98+ .id('btn_abn_offset')
99+ .onClick(async () => {
100+ let opts = this.baseOpts('AbnOffsetTitle', 'AbnMsg_offset', 'AbnOK_offset',
101+ 'offset_undefined');
102+ opts.offset = undefined;
103+ await this.runProbe('offset', opts);
104+ })
105+ Button('undefined borderWidth')
106+ .id('btn_abn_borderWidth')
107+ .onClick(async () => {
108+ let opts = this.baseOpts(
109+ 'AbnBWTitle', 'AbnMsg_borderWidth', 'AbnOK_borderWidth', 'borderWidth_undefined');
110+ opts.borderWidth = undefined;
111+ await this.runProbe('borderWidth', opts);
112+ })
113+ Button('undefined borderRadius')
114+ .id('btn_abn_borderRadius')
115+ .onClick(async () => {
116+ let opts = this.baseOpts(
117+ 'AbnBRTitle', 'AbnMsg_borderRadius', 'AbnOK_borderRadius',
118+ 'borderRadius_undefined');
119+ opts.borderRadius = undefined;
120+ await this.runProbe('borderRadius', opts);
121+ })
122+ Button('undefined shadow')
123+ .id('btn_abn_shadow')
124+ .onClick(async () => {
125+ let opts = this.baseOpts('AbnShadowTitle', 'AbnMsg_shadow', 'AbnOK_shadow',
126+ 'shadow_undefined');
127+ opts.shadow = undefined;
128+ await this.runProbe('shadow', opts);
129+ })
130+ Button('undefined autoCancel')
131+ .id('btn_abn_autoCancel')
132+ .onClick(async () => {
133+ let opts = this.baseOpts('AbnACTitle', 'AbnMsg_autoCancel', 'AbnOK_autoCancel',
134+ 'autoCancel_undefined');
135+ opts.autoCancel = undefined;
136+ await this.runProbe('autoCancel', opts);
137+ })
138+ Button('undefined isModal')
139+ .id('btn_abn_isModal')
140+ .onClick(async () => {
141+ let opts = this.baseOpts('AbnModalTitle', 'AbnMsg_isModal', 'AbnOK_isModal',
142+ 'isModal_undefined');
143+ opts.isModal = undefined;
144+ await this.runProbe('isModal', opts);
145+ })
146+ Button('undefined backgroundColor')
147+ .id('btn_abn_backgroundColor')
148+ .onClick(async () => {
149+ let opts = this.baseOpts('AbnBgTitle', 'AbnMsg_backgroundColor', 'AbnOK_backgroundColor',
150+ 'backgroundColor_undefined');
151+ opts.backgroundColor = undefined;
152+ await this.runProbe('backgroundColor', opts);
153+ })
154+ Button('undefined buttonDirection')
155+ .id('btn_abn_buttonDirection')
156+ .onClick(async () => {
157+ let opts = this.baseOpts('AbnDirTitle', 'AbnMsg_buttonDirection', 'AbnOK_buttonDirection',
158+ 'buttonDirection_undefined');
159+ opts.buttonDirection = undefined;
160+ await this.runProbe('buttonDirection', opts);
161+ })
162+ Button('undefined wordBreak')
163+ .id('btn_abn_wordBreak')
164+ .onClick(async () => {
165+ let msg: dialog.DialogMessage = {
166+ content: 'AbnWordBreakMsg',
167+ wordBreak: undefined
168+ };
169+ let opts: dialog.DialogStyleOptions = {
170+ title: 'AbnWBTitle',
171+ message: msg,
172+ buttons: [{
173+ value: 'AbnOK_wordBreak',
174+ action: () => {
175+ this.lastAction = 'wordBreak_undefined';
176+ }
177+ }]
178+ };
179+ await this.runProbe('wordBreak', opts);
180+ })
181+ Button('undefined levelMode')
182+ .id('btn_abn_levelMode')
183+ .onClick(async () => {
184+ let opts = this.baseOpts('AbnLevelTitle', 'AbnMsg_levelMode', 'AbnOK_levelMode',
185+ 'levelMode_undefined');
186+ opts.levelMode = undefined;
187+ await this.runProbe('levelMode', opts);
188+ })
189+ Button('undefined focusable')
190+ .id('btn_abn_focusable')
191+ .onClick(async () => {
192+ let opts = this.baseOpts('AbnFocusTitle', 'AbnMsg_focusable', 'AbnOK_focusable',
193+ 'focusable_undefined');
194+ opts.focusable = undefined;
195+ await this.runProbe('focusable', opts);
196+ })
197+ Button('omit optional all')
198+ .id('btn_abn_omit')
199+ .onClick(async () => {
200+ await this.runProbe('omit', this.baseOpts('AbnOmitTitle', 'AbnOmitMsg', 'AbnOmitOK',
201+ 'omit_ok'));
202+ })
203+ Button('null probe cover note')
204+ .id('btn_abn_null_note')
205+ .onClick(() => {
206+ this.coverFlag = 'null_compile_skip';
207+ this.lastAction = 'null_noted';
208+ })
209+ }
210+ .width('100%')
211+ .padding(12)
212+ }
213+ .width('100%')
214+ .height('100%')
215+ }
216+}
@@ -0,0 +1,143 @@
1+/**
2+ * Copyright (c) 2026 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+import {
17+ DialogPresenter,
18+ dialog,
19+} from '@kit.ArkUI';
20+ 
21+@Entry
22+@Component
23+struct DialogAbnormalOptsExtra {
24+ @State lastAction: string = 'none';
25+ @State lastError: string = 'none';
26+ @State coverFlag: string = 'none';
27+ 
28+ private presenter(): DialogPresenter {
29+ return this.getUIContext().getDialogPresenter();
30+ }
31+ 
32+ private baseOpts(title: string, msg: string, ok: string, act: string): dialog.DialogStyleOptions {
33+ return {
34+ title: title,
35+ message: { content: msg },
36+ buttons: [{
37+ value: ok,
38+ action: () => {
39+ this.lastAction = act;
40+ }
41+ }]
42+ };
43+ }
44+ 
45+ private async runProbe(tag: string, opts: dialog.DialogStyleOptions): Promise<void> {
46+ this.lastError = 'none';
47+ try {
48+ await this.presenter().present(opts);
49+ this.coverFlag = 'ok:' + tag;
50+ } catch (err) {
51+ this.lastError = String(err);
52+ this.coverFlag = 'fail:' + tag;
53+ this.lastAction = 'error';
54+ }
55+ }
56+ 
57+ build() {
58+ Column({ space: 6 }) {
59+ Text('DialogAbnormalOptsExtra').fontSize(16).fontWeight(FontWeight.Bold)
60+ Text('action=' + this.lastAction).id('abn_action')
61+ Text('error=' + this.lastError).id('abn_error')
62+ Text('cover=' + this.coverFlag).id('abn_cover')
63+ Button('undefined autoCancel')
64+ .id('btn_abn_autoCancel')
65+ .onClick(async () => {
66+ let opts = this.baseOpts('AbnACTitle', 'AbnMsg_autoCancel', 'AbnOK_autoCancel', 'autoCancel_undefined');
67+ opts.autoCancel = undefined;
68+ await this.runProbe('autoCancel', opts);
69+ })
70+ Button('undefined isModal')
71+ .id('btn_abn_isModal')
72+ .onClick(async () => {
73+ let opts = this.baseOpts('AbnModalTitle', 'AbnMsg_isModal', 'AbnOK_isModal', 'isModal_undefined');
74+ opts.isModal = undefined;
75+ await this.runProbe('isModal', opts);
76+ })
77+ Button('undefined backgroundColor')
78+ .id('btn_abn_backgroundColor')
79+ .onClick(async () => {
80+ let opts = this.baseOpts(
81+ 'AbnBgTitle', 'AbnMsg_backgroundColor', 'AbnOK_backgroundColor',
82+ 'backgroundColor_undefined');
83+ opts.backgroundColor = undefined;
84+ await this.runProbe('backgroundColor', opts);
85+ })
86+ Button('undefined buttonDirection')
87+ .id('btn_abn_buttonDirection')
88+ .onClick(async () => {
89+ let opts = this.baseOpts(
90+ 'AbnDirTitle', 'AbnMsg_buttonDirection', 'AbnOK_buttonDirection',
91+ 'buttonDirection_undefined');
92+ opts.buttonDirection = undefined;
93+ await this.runProbe('buttonDirection', opts);
94+ })
95+ Button('undefined wordBreak')
96+ .id('btn_abn_wordBreak')
97+ .onClick(async () => {
98+ let msg: dialog.DialogMessage = {
99+ content: 'AbnWordBreakMsg',
100+ wordBreak: undefined
101+ };
102+ let opts: dialog.DialogStyleOptions = {
103+ title: 'AbnWBTitle',
104+ message: msg,
105+ buttons: [{
106+ value: 'AbnOK_wordBreak',
107+ action: () => { this.lastAction = 'wordBreak_undefined'; }
108+ }]
109+ };
110+ await this.runProbe('wordBreak', opts);
111+ })
112+ Button('undefined levelMode')
113+ .id('btn_abn_levelMode')
114+ .onClick(async () => {
115+ let opts = this.baseOpts('AbnLevelTitle', 'AbnMsg_levelMode', 'AbnOK_levelMode', 'levelMode_undefined');
116+ opts.levelMode = undefined;
117+ await this.runProbe('levelMode', opts);
118+ })
119+ Button('undefined focusable')
120+ .id('btn_abn_focusable')
121+ .onClick(async () => {
122+ let opts = this.baseOpts('AbnFocusTitle', 'AbnMsg_focusable', 'AbnOK_focusable', 'focusable_undefined');
123+ opts.focusable = undefined;
124+ await this.runProbe('focusable', opts);
125+ })
126+ Button('omit optional all')
127+ .id('btn_abn_omit')
128+ .onClick(async () => {
129+ await this.runProbe('omit', this.baseOpts('AbnOmitTitle', 'AbnOmitMsg', 'AbnOmitOK',
130+ 'omit_ok'));
131+ })
132+ Button('null probe cover note')
133+ .id('btn_abn_null_note')
134+ .onClick(() => {
135+ this.coverFlag = 'null_compile_skip';
136+ this.lastAction = 'null_noted';
137+ })
138+ }
139+ .width('100%')
140+ .height('100%')
141+ .padding(12)
142+ }
143+}
@@ -0,0 +1,192 @@
1+/**
2+ * Copyright (c) 2026 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+import { DialogPresenter, DialogBaseAlignment } from '@kit.ArkUI';
17+ 
18+@Entry
19+@Component
20+struct DialogAlignWordBreak {
21+ @State lastAction: string = 'none';
22+ 
23+ private presenter(): DialogPresenter {
24+ return this.getUIContext().getDialogPresenter();
25+ }
26+ 
27+ build() {
28+ Scroll() {
29+ Column({ space: 8 }) {
30+ Text('Align x wordBreak part1').fontSize(16).fontWeight(FontWeight.Bold)
31+ Text('action=' + this.lastAction).id('align_wb_action')
32+ Button('TOP x NORMAL')
33+ .id('btn_aw_top_normal')
34+ .onClick(async () => {
35+ await this.presenter().present({
36+ title: 'AWTOP_NORMAL',
37+ message: {
38+ content: 'AlignWordBreakLongMessageContent_TOP_NORMAL',
39+ wordBreak: WordBreak.NORMAL
40+ },
41+ alignment: DialogBaseAlignment.TOP,
42+ width: '75%',
43+ buttons: [{
44+ value: 'OK_TOP_NORMAL',
45+ action: () => { this.lastAction = 'act_TOP_NORMAL'; }
46+ }]
47+ });
48+ })
49+ Button('TOP x BREAK_ALL')
50+ .id('btn_aw_top_break_all')
51+ .onClick(async () => {
52+ await this.presenter().present({
53+ title: 'AWTOP_BREAK_ALL',
54+ message: {
55+ content: 'AlignWordBreakLongMessageContent_TOP_BREAK_ALL',
56+ wordBreak: WordBreak.BREAK_ALL
57+ },
58+ alignment: DialogBaseAlignment.TOP,
59+ width: '75%',
60+ buttons: [{
61+ value: 'OK_TOP_BREAK_ALL',
62+ action: () => { this.lastAction = 'act_TOP_BREAK_ALL'; }
63+ }]
64+ });
65+ })
66+ Button('TOP x BREAK_WORD')
67+ .id('btn_aw_top_break_word')
68+ .onClick(async () => {
69+ await this.presenter().present({
70+ title: 'AWTOP_BREAK_WORD',
71+ message: {
72+ content: 'AlignWordBreakLongMessageContent_TOP_BREAK_WORD',
73+ wordBreak: WordBreak.BREAK_WORD
74+ },
75+ alignment: DialogBaseAlignment.TOP,
76+ width: '75%',
77+ buttons: [{
78+ value: 'OK_TOP_BREAK_WORD',
79+ action: () => { this.lastAction = 'act_TOP_BREAK_WORD'; }
80+ }]
81+ });
82+ })
83+ Button('CENTER x NORMAL')
84+ .id('btn_aw_center_normal')
85+ .onClick(async () => {
86+ await this.presenter().present({
87+ title: 'AWCENTER_NORMAL',
88+ message: {
89+ content: 'AlignWordBreakLongMessageContent_CENTER_NORMAL',
90+ wordBreak: WordBreak.NORMAL
91+ },
92+ alignment: DialogBaseAlignment.CENTER,
93+ width: '75%',
94+ buttons: [{
95+ value: 'OK_CENTER_NORMAL',
96+ action: () => { this.lastAction = 'act_CENTER_NORMAL'; }
97+ }]
98+ });
99+ })
100+ Button('CENTER x BREAK_ALL')
101+ .id('btn_aw_center_break_all')
102+ .onClick(async () => {
103+ await this.presenter().present({
104+ title: 'AWCENTER_BREAK_ALL',
105+ message: {
106+ content: 'AlignWordBreakLongMessageContent_CENTER_BREAK_ALL',
107+ wordBreak: WordBreak.BREAK_ALL
108+ },
109+ alignment: DialogBaseAlignment.CENTER,
110+ width: '75%',
111+ buttons: [{
112+ value: 'OK_CENTER_BREAK_ALL',
113+ action: () => { this.lastAction = 'act_CENTER_BREAK_ALL'; }
114+ }]
115+ });
116+ })
117+ Button('CENTER x BREAK_WORD')
118+ .id('btn_aw_center_break_word')
119+ .onClick(async () => {
120+ await this.presenter().present({
121+ title: 'AWCENTER_BREAK_WORD',
122+ message: {
123+ content: 'AlignWordBreakLongMessageContent_CENTER_BREAK_WORD',
124+ wordBreak: WordBreak.BREAK_WORD
125+ },
126+ alignment: DialogBaseAlignment.CENTER,
127+ width: '75%',
128+ buttons: [{
129+ value: 'OK_CENTER_BREAK_WORD',
130+ action: () => { this.lastAction = 'act_CENTER_BREAK_WORD'; }
131+ }]
132+ });
133+ })
134+ Button('BOTTOM x NORMAL')
135+ .id('btn_aw_bottom_normal')
136+ .onClick(async () => {
137+ await this.presenter().present({
138+ title: 'AWBOTTOM_NORMAL',
139+ message: {
140+ content: 'AlignWordBreakLongMessageContent_BOTTOM_NORMAL',
141+ wordBreak: WordBreak.NORMAL
142+ },
143+ alignment: DialogBaseAlignment.BOTTOM,
144+ width: '75%',
145+ buttons: [{
146+ value: 'OK_BOTTOM_NORMAL',
147+ action: () => { this.lastAction = 'act_BOTTOM_NORMAL'; }
148+ }]
149+ });
150+ })
151+ Button('BOTTOM x BREAK_ALL')
152+ .id('btn_aw_bottom_break_all')
153+ .onClick(async () => {
154+ await this.presenter().present({
155+ title: 'AWBOTTOM_BREAK_ALL',
156+ message: {
157+ content: 'AlignWordBreakLongMessageContent_BOTTOM_BREAK_ALL',
158+ wordBreak: WordBreak.BREAK_ALL
159+ },
160+ alignment: DialogBaseAlignment.BOTTOM,
161+ width: '75%',
162+ buttons: [{
163+ value: 'OK_BOTTOM_BREAK_ALL',
164+ action: () => { this.lastAction = 'act_BOTTOM_BREAK_ALL'; }
165+ }]
166+ });
167+ })
168+ Button('BOTTOM x BREAK_WORD')
169+ .id('btn_aw_bottom_break_word')
170+ .onClick(async () => {
171+ await this.presenter().present({
172+ title: 'AWBOTTOM_BREAK_WORD',
173+ message: {
174+ content: 'AlignWordBreakLongMessageContent_BOTTOM_BREAK_WORD',
175+ wordBreak: WordBreak.BREAK_WORD
176+ },
177+ alignment: DialogBaseAlignment.BOTTOM,
178+ width: '75%',
179+ buttons: [{
180+ value: 'OK_BOTTOM_BREAK_WORD',
181+ action: () => { this.lastAction = 'act_BOTTOM_BREAK_WORD'; }
182+ }]
183+ });
184+ })
185+ }
186+ .width('100%')
187+ .padding(12)
188+ }
189+ .width('100%')
190+ .height('100%')
191+ }
192+}
@@ -0,0 +1,192 @@
1+/**
2+ * Copyright (c) 2026 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+import { DialogPresenter, DialogBaseAlignment } from '@kit.ArkUI';
17+ 
18+@Entry
19+@Component
20+struct DialogAlignWordBreakExtra {
21+ @State lastAction: string = 'none';
22+ 
23+ private presenter(): DialogPresenter {
24+ return this.getUIContext().getDialogPresenter();
25+ }
26+ 
27+ build() {
28+ Scroll() {
29+ Column({ space: 8 }) {
30+ Text('Align x wordBreak part2').fontSize(16).fontWeight(FontWeight.Bold)
31+ Text('action=' + this.lastAction).id('align_wb_action')
32+ Button('DEFAULT x NORMAL')
33+ .id('btn_aw_default_normal')
34+ .onClick(async () => {
35+ await this.presenter().present({
36+ title: 'AWDEFAULT_NORMAL',
37+ message: {
38+ content: 'AlignWordBreakLongMessageContent_DEFAULT_NORMAL',
39+ wordBreak: WordBreak.NORMAL
40+ },
41+ alignment: DialogBaseAlignment.DEFAULT,
42+ width: '75%',
43+ buttons: [{
44+ value: 'OK_DEFAULT_NORMAL',
45+ action: () => { this.lastAction = 'act_DEFAULT_NORMAL'; }
46+ }]
47+ });
48+ })
49+ Button('DEFAULT x BREAK_ALL')
50+ .id('btn_aw_default_break_all')
51+ .onClick(async () => {
52+ await this.presenter().present({
53+ title: 'AWDEFAULT_BREAK_ALL',
54+ message: {
55+ content: 'AlignWordBreakLongMessageContent_DEFAULT_BREAK_ALL',
56+ wordBreak: WordBreak.BREAK_ALL
57+ },
58+ alignment: DialogBaseAlignment.DEFAULT,
59+ width: '75%',
60+ buttons: [{
61+ value: 'OK_DEFAULT_BREAK_ALL',
62+ action: () => { this.lastAction = 'act_DEFAULT_BREAK_ALL'; }
63+ }]
64+ });
65+ })
66+ Button('DEFAULT x BREAK_WORD')
67+ .id('btn_aw_default_break_word')
68+ .onClick(async () => {
69+ await this.presenter().present({
70+ title: 'AWDEFAULT_BREAK_WORD',
71+ message: {
72+ content: 'AlignWordBreakLongMessageContent_DEFAULT_BREAK_WORD',
73+ wordBreak: WordBreak.BREAK_WORD
74+ },
75+ alignment: DialogBaseAlignment.DEFAULT,
76+ width: '75%',
77+ buttons: [{
78+ value: 'OK_DEFAULT_BREAK_WORD',
79+ action: () => { this.lastAction = 'act_DEFAULT_BREAK_WORD'; }
80+ }]
81+ });
82+ })
83+ Button('TOP_START x NORMAL')
84+ .id('btn_aw_top_start_normal')
85+ .onClick(async () => {
86+ await this.presenter().present({
87+ title: 'AWTOP_START_NORMAL',
88+ message: {
89+ content: 'AlignWordBreakLongMessageContent_TOP_START_NORMAL',
90+ wordBreak: WordBreak.NORMAL
91+ },
92+ alignment: DialogBaseAlignment.TOP_START,
93+ width: '75%',
94+ buttons: [{
95+ value: 'OK_TOP_START_NORMAL',
96+ action: () => { this.lastAction = 'act_TOP_START_NORMAL'; }
97+ }]
98+ });
99+ })
100+ Button('TOP_START x BREAK_ALL')
101+ .id('btn_aw_top_start_break_all')
102+ .onClick(async () => {
103+ await this.presenter().present({
104+ title: 'AWTOP_START_BREAK_ALL',
105+ message: {
106+ content: 'AlignWordBreakLongMessageContent_TOP_START_BREAK_ALL',
107+ wordBreak: WordBreak.BREAK_ALL
108+ },
109+ alignment: DialogBaseAlignment.TOP_START,
110+ width: '75%',
111+ buttons: [{
112+ value: 'OK_TOP_START_BREAK_ALL',
113+ action: () => { this.lastAction = 'act_TOP_START_BREAK_ALL'; }
114+ }]
115+ });
116+ })
117+ Button('TOP_START x BREAK_WORD')
118+ .id('btn_aw_top_start_break_word')
119+ .onClick(async () => {
120+ await this.presenter().present({
121+ title: 'AWTOP_START_BREAK_WORD',
122+ message: {
123+ content: 'AlignWordBreakLongMessageContent_TOP_START_BREAK_WORD',
124+ wordBreak: WordBreak.BREAK_WORD
125+ },
126+ alignment: DialogBaseAlignment.TOP_START,
127+ width: '75%',
128+ buttons: [{
129+ value: 'OK_TOP_START_BREAK_WORD',
130+ action: () => { this.lastAction = 'act_TOP_START_BREAK_WORD'; }
131+ }]
132+ });
133+ })
134+ Button('TOP_END x NORMAL')
135+ .id('btn_aw_top_end_normal')
136+ .onClick(async () => {
137+ await this.presenter().present({
138+ title: 'AWTOP_END_NORMAL',
139+ message: {
140+ content: 'AlignWordBreakLongMessageContent_TOP_END_NORMAL',
141+ wordBreak: WordBreak.NORMAL
142+ },
143+ alignment: DialogBaseAlignment.TOP_END,
144+ width: '75%',
145+ buttons: [{
146+ value: 'OK_TOP_END_NORMAL',
147+ action: () => { this.lastAction = 'act_TOP_END_NORMAL'; }
148+ }]
149+ });
150+ })
151+ Button('TOP_END x BREAK_ALL')
152+ .id('btn_aw_top_end_break_all')
153+ .onClick(async () => {
154+ await this.presenter().present({
155+ title: 'AWTOP_END_BREAK_ALL',
156+ message: {
157+ content: 'AlignWordBreakLongMessageContent_TOP_END_BREAK_ALL',
158+ wordBreak: WordBreak.BREAK_ALL
159+ },
160+ alignment: DialogBaseAlignment.TOP_END,
161+ width: '75%',
162+ buttons: [{
163+ value: 'OK_TOP_END_BREAK_ALL',
164+ action: () => { this.lastAction = 'act_TOP_END_BREAK_ALL'; }
165+ }]
166+ });
167+ })
168+ Button('TOP_END x BREAK_WORD')
169+ .id('btn_aw_top_end_break_word')
170+ .onClick(async () => {
171+ await this.presenter().present({
172+ title: 'AWTOP_END_BREAK_WORD',
173+ message: {
174+ content: 'AlignWordBreakLongMessageContent_TOP_END_BREAK_WORD',
175+ wordBreak: WordBreak.BREAK_WORD
176+ },
177+ alignment: DialogBaseAlignment.TOP_END,
178+ width: '75%',
179+ buttons: [{
180+ value: 'OK_TOP_END_BREAK_WORD',
181+ action: () => { this.lastAction = 'act_TOP_END_BREAK_WORD'; }
182+ }]
183+ });
184+ })
185+ }
186+ .width('100%')
187+ .padding(12)
188+ }
189+ .width('100%')
190+ .height('100%')
191+ }
192+}
@@ -0,0 +1,150 @@
1+/**
2+ * Copyright (c) 2026 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+import {
17+ DialogPresenter,
18+ DialogBaseController,
19+ DialogState,
20+ DialogResult,
21+ DialogDismissal,
22+ dialog,
23+} from '@kit.ArkUI';
24+ 
25+@Entry
26+@Component
27+struct DialogBaseControllerLife {
28+ @State lastAction: string = 'none';
29+ @State stateBefore: string = 'none';
30+ @State stateAfter: string = 'none';
31+ @State dismissReason: string = 'none';
32+ @State dialogId: number = -1;
33+ private controller: DialogBaseController = new DialogBaseController();
34+ 
35+ private presenter(): DialogPresenter {
36+ return this.getUIContext().getDialogPresenter();
37+ }
38+ 
39+ private stateName(state: DialogState): string {
40+ switch (state) {
41+ case DialogState.UNINITIALIZED:
42+ return 'UNINITIALIZED';
43+ case DialogState.INITIALIZED:
44+ return 'INITIALIZED';
45+ case DialogState.APPEARING:
46+ return 'APPEARING';
47+ case DialogState.APPEARED:
48+ return 'APPEARED';
49+ case DialogState.DISAPPEARING:
50+ return 'DISAPPEARING';
51+ case DialogState.DISAPPEARED:
52+ return 'DISAPPEARED';
53+ default:
54+ return 'UNKNOWN';
55+ }
56+ }
57+ 
58+ build() {
59+ Column({ space: 10 }) {
60+ Text('DialogBaseController lifecycle').fontSize(18).fontWeight(FontWeight.Bold)
61+ Text('action=' + this.lastAction).id('ctrl_action')
62+ Text('stateBefore=' + this.stateBefore).id('ctrl_state_before')
63+ Text('stateAfter=' + this.stateAfter).id('ctrl_state_after')
64+ Text('dismissReason=' + this.dismissReason).id('ctrl_dismiss_reason')
65+ Text('dialogId=' + this.dialogId).id('ctrl_dialog_id')
66+ Button('present with controller')
67+ .id('btn_ctrl_present')
68+ .onClick(async () => {
69+ this.controller = new DialogBaseController();
70+ this.stateBefore = this.stateName(this.controller.getState());
71+ let opts: dialog.DialogStyleOptions = {
72+ title: 'CtrlTitle',
73+ message: { content: 'CtrlMessage' },
74+ controller: this.controller,
75+ buttons: [
76+ {
77+ value: 'CtrlOK',
78+ action: () => {
79+ this.lastAction = 'CtrlOK';
80+ }
81+ }
82+ ]
83+ };
84+ let result: DialogResult = await this.presenter().present(opts);
85+ this.dialogId = result.dialogId;
86+ this.stateAfter = this.stateName(this.controller.getState());
87+ })
88+ Button('present then auto close')
89+ .id('btn_ctrl_auto_close')
90+ .onClick(async () => {
91+ this.controller = new DialogBaseController();
92+ let opts: dialog.DialogStyleOptions = {
93+ title: 'AutoCloseTitle',
94+ message: { content: 'AutoCloseMessage' },
95+ controller: this.controller,
96+ onDidAppear: () => {
97+ this.stateAfter = this.stateName(this.controller.getState());
98+ this.controller.close();
99+ this.lastAction = 'closed';
100+ this.stateAfter = this.stateName(this.controller.getState());
101+ },
102+ buttons: [
103+ {
104+ value: 'AutoCloseOK',
105+ action: () => {
106+ this.lastAction = 'AutoCloseOK';
107+ }
108+ }
109+ ]
110+ };
111+ let result: DialogResult = await this.presenter().present(opts);
112+ this.dialogId = result.dialogId;
113+ })
114+ Button('onWillDismiss')
115+ .id('btn_ctrl_will_dismiss')
116+ .onClick(async () => {
117+ let opts: dialog.DialogStyleOptions = {
118+ title: 'WillDismissTitle',
119+ message: { content: 'WillDismissMessage' },
120+ autoCancel: true,
121+ onWillDismiss: (dismissal: DialogDismissal) => {
122+ this.dismissReason = String(dismissal.reason);
123+ this.lastAction = 'willDismiss';
124+ dismissal.dismiss();
125+ },
126+ buttons: [
127+ {
128+ value: 'WillDismissOK',
129+ action: () => {
130+ this.lastAction = 'WillDismissOK';
131+ }
132+ }
133+ ]
134+ };
135+ await this.presenter().present(opts);
136+ })
137+ Button('construct getState only')
138+ .id('btn_ctrl_construct')
139+ .onClick(() => {
140+ let c = new DialogBaseController();
141+ this.stateBefore = this.stateName(c.getState());
142+ this.lastAction = 'constructed';
143+ })
144+ }
145+ .width('100%')
146+ .height('100%')
147+ .padding(16)
148+ .justifyContent(FlexAlign.Center)
149+ }
150+}
@@ -0,0 +1,118 @@
1+/**
2+ * Copyright (c) 2026 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+import {
17+ DialogPresenter,
18+ DialogBaseAlignment,
19+} from '@kit.ArkUI';
20+ 
21+@Entry
22+@Component
23+struct DialogBaseOptionsLayout {
24+ @State lastAction: string = 'none';
25+ @State lastAlign: string = 'none';
26+ 
27+ private presenter(): DialogPresenter {
28+ return this.getUIContext().getDialogPresenter();
29+ }
30+ 
31+ private async openAlign(tag: string, align: DialogBaseAlignment): Promise<void> {
32+ this.lastAlign = tag;
33+ await this.presenter().present({
34+ title: 'Align' + tag,
35+ message: { content: 'AlignMsg' + tag },
36+ alignment: align,
37+ width: '80%',
38+ height: 220,
39+ offset: { dx: 0, dy: 10 },
40+ borderWidth: 2,
41+ borderColor: Color.Blue,
42+ borderStyle: BorderStyle.Solid,
43+ borderRadius: 12,
44+ buttons: [
45+ {
46+ value: 'AlignOK',
47+ action: () => {
48+ this.lastAction = 'AlignOK_' + tag;
49+ }
50+ }
51+ ]
52+ });
53+ }
54+ 
55+ build() {
56+ Scroll() {
57+ Column({ space: 8 }) {
58+ Text('DialogBaseOptions layout').fontSize(18).fontWeight(FontWeight.Bold)
59+ Text('align=' + this.lastAlign).id('base_layout_align')
60+ Text('action=' + this.lastAction).id('base_layout_action')
61+ Button('TOP').id('btn_align_TOP').onClick(() => {
62+ this.openAlign('TOP', DialogBaseAlignment.TOP);
63+ })
64+ Button('CENTER').id('btn_align_CENTER').onClick(() => {
65+ this.openAlign('CENTER', DialogBaseAlignment.CENTER);
66+ })
67+ Button('BOTTOM').id('btn_align_BOTTOM').onClick(() => {
68+ this.openAlign('BOTTOM', DialogBaseAlignment.BOTTOM);
69+ })
70+ Button('DEFAULT').id('btn_align_DEFAULT').onClick(() => {
71+ this.openAlign('DEFAULT', DialogBaseAlignment.DEFAULT);
72+ })
73+ Button('TOP_START').id('btn_align_TOP_START').onClick(() => {
74+ this.openAlign('TOP_START', DialogBaseAlignment.TOP_START);
75+ })
76+ Button('TOP_END').id('btn_align_TOP_END').onClick(() => {
77+ this.openAlign('TOP_END', DialogBaseAlignment.TOP_END);
78+ })
79+ Button('CENTER_START').id('btn_align_CENTER_START').onClick(() => {
80+ this.openAlign('CENTER_START', DialogBaseAlignment.CENTER_START);
81+ })
82+ Button('CENTER_END').id('btn_align_CENTER_END').onClick(() => {
83+ this.openAlign('CENTER_END', DialogBaseAlignment.CENTER_END);
84+ })
85+ Button('BOTTOM_START').id('btn_align_BOTTOM_START').onClick(() => {
86+ this.openAlign('BOTTOM_START', DialogBaseAlignment.BOTTOM_START);
87+ })
88+ Button('BOTTOM_END').id('btn_align_BOTTOM_END').onClick(() => {
89+ this.openAlign('BOTTOM_END', DialogBaseAlignment.BOTTOM_END);
90+ })
91+ Button('maskRect offset')
92+ .id('btn_layout_mask')
93+ .onClick(async () => {
94+ await this.presenter().present({
95+ title: 'MaskRectTitle',
96+ message: { content: 'MaskRectMessage' },
97+ maskRect: { x: 0, y: 0, width: '100%', height: '100%' },
98+ offset: { dx: 8, dy: -8 },
99+ width: 280,
100+ height: 180,
101+ buttons: [
102+ {
103+ value: 'MaskOK',
104+ action: () => {
105+ this.lastAction = 'MaskOK';
106+ }
107+ }
108+ ]
109+ });
110+ })
111+ }
112+ .width('100%')
113+ .padding(16)
114+ }
115+ .width('100%')
116+ .height('100%')
117+ }
118+}
@@ -0,0 +1,222 @@
1+/**
2+ * Copyright (c) 2026 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+import {
17+ DialogPresenter,
18+ LevelMode,
19+ ImmersiveMode,
20+ LevelOrder,
21+ LengthMetrics,
22+} from '@kit.ArkUI';
23+import uiMaterial from '@ohos.arkui.uiMaterial';
24+ 
25+@Entry
26+@Component
27+struct DialogBaseOptionsVisual {
28+ @State lastAction: string = 'none';
29+ 
30+ private presenter(): DialogPresenter {
31+ return this.getUIContext().getDialogPresenter();
32+ }
33+ 
34+ build() {
35+ Scroll() {
36+ Column({ space: 10 }) {
37+ Text('DialogBaseOptions visual').fontSize(18).fontWeight(FontWeight.Bold)
38+ Text('action=' + this.lastAction).id('base_visual_action')
39+ Button('backgroundColor blur')
40+ .id('btn_visual_bg')
41+ .onClick(async () => {
42+ await this.presenter().present({
43+ title: 'BgTitle',
44+ message: { content: 'BgMessage' },
45+ backgroundColor: '#EEF5FF',
46+ backgroundBlurStyle: BlurStyle.Thin,
47+ backgroundBlurStyleOptions: {
48+ policy: BlurStyleActivePolicy.ALWAYS_ACTIVE,
49+ scale: 0.6
50+ },
51+ maskColor: '#66000000',
52+ shadow: ShadowStyle.OUTER_DEFAULT_MD,
53+ buttons: [
54+ {
55+ value: 'BgOK',
56+ action: () => {
57+ this.lastAction = 'BgOK';
58+ }
59+ }
60+ ]
61+ });
62+ })
63+ Button('backgroundEffect')
64+ .id('btn_visual_effect')
65+ .onClick(async () => {
66+ await this.presenter().present({
67+ title: 'EffectTitle',
68+ message: { content: 'EffectMessage' },
69+ backgroundEffect: {
70+ radius: 20,
71+ saturation: 1.1,
72+ brightness: 1.0,
73+ color: '#AA99FF'
74+ },
75+ buttons: [
76+ {
77+ value: 'EffectOK',
78+ action: () => {
79+ this.lastAction = 'EffectOK';
80+ }
81+ }
82+ ]
83+ });
84+ })
85+ Button('levelMode OVERLAY')
86+ .id('btn_visual_level_overlay')
87+ .onClick(async () => {
88+ await this.presenter().present({
89+ title: 'LevelOverlay',
90+ message: { content: 'LevelOverlayMsg' },
91+ levelMode: LevelMode.OVERLAY,
92+ immersiveMode: ImmersiveMode.DEFAULT,
93+ levelOrder: LevelOrder.clamp(1),
94+ buttons: [
95+ {
96+ value: 'LevelOK',
97+ action: () => {
98+ this.lastAction = 'LevelOK';
99+ }
100+ }
101+ ]
102+ });
103+ })
104+ Button('levelMode EMBEDDED')
105+ .id('btn_visual_level_embedded')
106+ .onClick(async () => {
107+ await this.presenter().present({
108+ title: 'LevelEmbedded',
109+ message: { content: 'LevelEmbeddedMsg' },
110+ levelMode: LevelMode.EMBEDDED,
111+ immersiveMode: ImmersiveMode.EXTEND,
112+ buttons: [
113+ {
114+ value: 'EmbedOK',
115+ action: () => {
116+ this.lastAction = 'EmbedOK';
117+ }
118+ }
119+ ]
120+ });
121+ })
122+ Button('isModal false')
123+ .id('btn_visual_not_modal')
124+ .onClick(async () => {
125+ await this.presenter().present({
126+ title: 'NotModal',
127+ message: { content: 'NotModalMsg' },
128+ isModal: false,
129+ autoCancel: true,
130+ focusable: true,
131+ buttons: [
132+ {
133+ value: 'ModalOK',
134+ action: () => {
135+ this.lastAction = 'ModalOK';
136+ }
137+ }
138+ ]
139+ });
140+ })
141+ Button('hover mode opts')
142+ .id('btn_visual_hover')
143+ .onClick(async () => {
144+ await this.presenter().present({
145+ title: 'HoverTitle',
146+ message: { content: 'HoverMessage' },
147+ enableHoverMode: true,
148+ hoverModeArea: HoverModeAreaType.BOTTOM_SCREEN,
149+ buttons: [
150+ {
151+ value: 'HoverOK',
152+ action: () => {
153+ this.lastAction = 'HoverOK';
154+ }
155+ }
156+ ]
157+ });
158+ })
159+ Button('transition keyboard')
160+ .id('btn_visual_transition')
161+ .onClick(async () => {
162+ await this.presenter().present({
163+ title: 'TransTitle',
164+ message: { content: 'TransMessage' },
165+ dialogTransition: TransitionEffect.OPACITY,
166+ maskTransition: TransitionEffect.OPACITY,
167+ keyboardAvoidMode: KeyboardAvoidMode.DEFAULT,
168+ keyboardAvoidDistance: LengthMetrics.vp(12),
169+ buttons: [
170+ {
171+ value: 'TransOK',
172+ action: () => {
173+ this.lastAction = 'TransOK';
174+ }
175+ }
176+ ]
177+ });
178+ })
179+ Button('levelUniqueId embed')
180+ .id('btn_visual_level_uid')
181+ .onClick(async () => {
182+ await this.presenter().present({
183+ title: 'LevelUidTitle',
184+ message: { content: 'LevelUidMessage' },
185+ levelMode: LevelMode.EMBEDDED,
186+ levelUniqueId: 1,
187+ immersiveMode: ImmersiveMode.DEFAULT,
188+ buttons: [
189+ {
190+ value: 'UidOK',
191+ action: () => {
192+ this.lastAction = 'UidOK';
193+ }
194+ }
195+ ]
196+ });
197+ })
198+ Button('systemMaterial')
199+ .id('btn_visual_material')
200+ .onClick(async () => {
201+ await this.presenter().present({
202+ title: 'MaterialTitle',
203+ message: { content: 'MaterialMessage' },
204+ systemMaterial: uiMaterial.Material.empty,
205+ buttons: [
206+ {
207+ value: 'MaterialOK',
208+ action: () => {
209+ this.lastAction = 'MaterialOK';
210+ }
211+ }
212+ ]
213+ });
214+ })
215+ }
216+ .width('100%')
217+ .padding(16)
218+ }
219+ .width('100%')
220+ .height('100%')
221+ }
222+}
@@ -0,0 +1,163 @@
1+/**
2+ * Copyright (c) 2026 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+import { DialogPresenter, LengthMetrics } from '@kit.ArkUI';
17+ 
18+@Entry
19+@Component
20+struct DialogBaseSizeBorder {
21+ @State lastAction: string = 'none';
22+ 
23+ private presenter(): DialogPresenter {
24+ return this.getUIContext().getDialogPresenter();
25+ }
26+ 
27+ build() {
28+ Scroll() {
29+ Column({ space: 8 }) {
30+ Text('DialogBaseOptions size border').fontSize(18).fontWeight(FontWeight.Bold)
31+ Text('action=' + this.lastAction).id('size_border_action')
32+ Button('width percent')
33+ .id('btn_size_width_pct')
34+ .onClick(async () => {
35+ await this.presenter().present({
36+ title: 'WidthPctTitle',
37+ message: { content: 'WidthPctMsg' },
38+ width: '70%',
39+ buttons: [{ value: 'WidthPctOK', action: () => { this.lastAction = 'WidthPctOK'; } }]
40+ });
41+ })
42+ Button('width number')
43+ .id('btn_size_width_num')
44+ .onClick(async () => {
45+ await this.presenter().present({
46+ title: 'WidthNumTitle',
47+ message: { content: 'WidthNumMsg' },
48+ width: 300,
49+ buttons: [{ value: 'WidthNumOK', action: () => { this.lastAction = 'WidthNumOK'; } }]
50+ });
51+ })
52+ Button('height number')
53+ .id('btn_size_height')
54+ .onClick(async () => {
55+ await this.presenter().present({
56+ title: 'HeightTitle',
57+ message: { content: 'HeightMsg' },
58+ height: 240,
59+ buttons: [{ value: 'HeightOK', action: () => { this.lastAction = 'HeightOK'; } }]
60+ });
61+ })
62+ Button('borderWidth')
63+ .id('btn_size_bw')
64+ .onClick(async () => {
65+ await this.presenter().present({
66+ title: 'BWTitle',
67+ message: { content: 'BWMsg' },
68+ borderWidth: 4,
69+ borderColor: Color.Red,
70+ buttons: [{ value: 'BWOK', action: () => { this.lastAction = 'BWOK'; } }]
71+ });
72+ })
73+ Button('borderRadius')
74+ .id('btn_size_br')
75+ .onClick(async () => {
76+ await this.presenter().present({
77+ title: 'BRTitle',
78+ message: { content: 'BRMsg' },
79+ borderRadius: 20,
80+ buttons: [{ value: 'BROK', action: () => { this.lastAction = 'BROK'; } }]
81+ });
82+ })
83+ Button('borderStyle dashed')
84+ .id('btn_size_bs')
85+ .onClick(async () => {
86+ await this.presenter().present({
87+ title: 'BSTitle',
88+ message: { content: 'BSMsg' },
89+ borderWidth: 2,
90+ borderStyle: BorderStyle.Dashed,
91+ borderColor: Color.Green,
92+ buttons: [{ value: 'BSOK', action: () => { this.lastAction = 'BSOK'; } }]
93+ });
94+ })
95+ Button('offset dx dy')
96+ .id('btn_size_offset')
97+ .onClick(async () => {
98+ await this.presenter().present({
99+ title: 'OffsetTitle',
100+ message: { content: 'OffsetMsg' },
101+ offset: { dx: 12, dy: -16 },
102+ buttons: [{ value: 'OffsetOK', action: () => { this.lastAction = 'OffsetOK'; } }]
103+ });
104+ })
105+ Button('maskColor')
106+ .id('btn_size_mask')
107+ .onClick(async () => {
108+ await this.presenter().present({
109+ title: 'MaskColorTitle',
110+ message: { content: 'MaskColorMsg' },
111+ maskColor: '#88000000',
112+ buttons: [{ value: 'MaskColorOK', action: () => { this.lastAction = 'MaskColorOK'; } }]
113+ });
114+ })
115+ Button('autoCancel false')
116+ .id('btn_size_ac')
117+ .onClick(async () => {
118+ await this.presenter().present({
119+ title: 'ACTitle',
120+ message: { content: 'ACMsg' },
121+ autoCancel: false,
122+ buttons: [{ value: 'ACOK', action: () => { this.lastAction = 'ACOK'; } }]
123+ });
124+ })
125+ Button('focusable false')
126+ .id('btn_size_focusable')
127+ .onClick(async () => {
128+ await this.presenter().present({
129+ title: 'FocusableTitle',
130+ message: { content: 'FocusableMsg' },
131+ focusable: false,
132+ buttons: [{ value: 'FocusableOK', action: () => { this.lastAction = 'FocusableOK'; } }]
133+ });
134+ })
135+ Button('keyboardAvoidMode')
136+ .id('btn_size_kbd')
137+ .onClick(async () => {
138+ await this.presenter().present({
139+ title: 'KbdTitle',
140+ message: { content: 'KbdMsg' },
141+ keyboardAvoidMode: KeyboardAvoidMode.DEFAULT,
142+ keyboardAvoidDistance: LengthMetrics.vp(16),
143+ buttons: [{ value: 'KbdOK', action: () => { this.lastAction = 'KbdOK'; } }]
144+ });
145+ })
146+ Button('shadow OUTER')
147+ .id('btn_size_shadow')
148+ .onClick(async () => {
149+ await this.presenter().present({
150+ title: 'ShadowTitle',
151+ message: { content: 'ShadowMsg' },
152+ shadow: ShadowStyle.OUTER_DEFAULT_SM,
153+ buttons: [{ value: 'ShadowOK', action: () => { this.lastAction = 'ShadowOK'; } }]
154+ });
155+ })
156+ }
157+ .width('100%')
158+ .padding(16)
159+ }
160+ .width('100%')
161+ .height('100%')
162+ }
163+}
@@ -0,0 +1,182 @@
1+/**
2+ * Copyright (c) 2026 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+import { DialogPresenter } from '@kit.ArkUI';
17+ 
18+@Entry
19+@Component
20+struct DialogButtonMatrix {
21+ @State lastAction: string = 'none';
22+ 
23+ private presenter(): DialogPresenter {
24+ return this.getUIContext().getDialogPresenter();
25+ }
26+ 
27+ build() {
28+ Scroll() {
29+ Column({ space: 8 }) {
30+ Text('DialogButton property matrix').fontSize(18).fontWeight(FontWeight.Bold)
31+ Text('action=' + this.lastAction).id('btn_matrix_action')
32+ Button('value only')
33+ .id('btn_matrix_value')
34+ .onClick(async () => {
35+ await this.presenter().present({
36+ title: 'ValueTitle',
37+ message: { content: 'ValueMsg' },
38+ buttons: [{
39+ value: 'ValueOK',
40+ action: () => { this.lastAction = 'ValueOK'; }
41+ }]
42+ });
43+ })
44+ Button('fontColor')
45+ .id('btn_matrix_font')
46+ .onClick(async () => {
47+ await this.presenter().present({
48+ title: 'FontTitle',
49+ message: { content: 'FontMsg' },
50+ buttons: [{
51+ value: 'FontOK',
52+ fontColor: Color.Red,
53+ action: () => { this.lastAction = 'FontOK'; }
54+ }]
55+ });
56+ })
57+ Button('backgroundColor')
58+ .id('btn_matrix_bg')
59+ .onClick(async () => {
60+ await this.presenter().present({
61+ title: 'BgBtnTitle',
62+ message: { content: 'BgBtnMsg' },
63+ buttons: [{
64+ value: 'BgBtnOK',
65+ backgroundColor: Color.Orange,
66+ action: () => { this.lastAction = 'BgBtnOK'; }
67+ }]
68+ });
69+ })
70+ Button('enabled true')
71+ .id('btn_matrix_enabled')
72+ .onClick(async () => {
73+ await this.presenter().present({
74+ title: 'EnabledTitle',
75+ message: { content: 'EnabledMsg' },
76+ buttons: [{
77+ value: 'EnabledOK',
78+ enabled: true,
79+ action: () => { this.lastAction = 'EnabledOK'; }
80+ }]
81+ });
82+ })
83+ Button('defaultFocus')
84+ .id('btn_matrix_focus')
85+ .onClick(async () => {
86+ await this.presenter().present({
87+ title: 'FocusTitle',
88+ message: { content: 'FocusMsg' },
89+ buttons: [{
90+ value: 'FocusOK',
91+ defaultFocus: true,
92+ action: () => { this.lastAction = 'FocusOK'; }
93+ }]
94+ });
95+ })
96+ Button('primary true')
97+ .id('btn_matrix_primary')
98+ .onClick(async () => {
99+ await this.presenter().present({
100+ title: 'PrimaryTitle',
101+ message: { content: 'PrimaryMsg' },
102+ buttons: [{
103+ value: 'PrimaryOK',
104+ primary: true,
105+ action: () => { this.lastAction = 'PrimaryOK'; }
106+ }]
107+ });
108+ })
109+ Button('style DEFAULT')
110+ .id('btn_matrix_style_def')
111+ .onClick(async () => {
112+ await this.presenter().present({
113+ title: 'StyleDefTitle',
114+ message: { content: 'StyleDefMsg' },
115+ buttons: [{
116+ value: 'StyleDefOK',
117+ style: DialogButtonStyle.DEFAULT,
118+ action: () => { this.lastAction = 'StyleDefOK'; }
119+ }]
120+ });
121+ })
122+ Button('style HIGHLIGHT')
123+ .id('btn_matrix_style_hi')
124+ .onClick(async () => {
125+ await this.presenter().present({
126+ title: 'StyleHiTitle',
127+ message: { content: 'StyleHiMsg' },
128+ buttons: [{
129+ value: 'StyleHiOK',
130+ style: DialogButtonStyle.HIGHLIGHT,
131+ action: () => { this.lastAction = 'StyleHiOK'; }
132+ }]
133+ });
134+ })
135+ Button('two buttons mix')
136+ .id('btn_matrix_mix')
137+ .onClick(async () => {
138+ await this.presenter().present({
139+ title: 'MixTitle',
140+ message: { content: 'MixMsg' },
141+ buttons: [
142+ {
143+ value: 'MixCancel',
144+ fontColor: Color.Gray,
145+ enabled: true,
146+ primary: false,
147+ style: DialogButtonStyle.DEFAULT,
148+ action: () => { this.lastAction = 'MixCancel'; }
149+ },
150+ {
151+ value: 'MixOK',
152+ fontColor: Color.White,
153+ backgroundColor: Color.Blue,
154+ enabled: true,
155+ defaultFocus: true,
156+ primary: true,
157+ style: DialogButtonStyle.HIGHLIGHT,
158+ action: () => { this.lastAction = 'MixOK'; }
159+ }
160+ ]
161+ });
162+ })
163+ Button('action callback')
164+ .id('btn_matrix_action_cb')
165+ .onClick(async () => {
166+ await this.presenter().present({
167+ title: 'ActionTitle',
168+ message: { content: 'ActionMsg' },
169+ buttons: [{
170+ value: 'ActionOK',
171+ action: () => { this.lastAction = 'ActionFired'; }
172+ }]
173+ });
174+ })
175+ }
176+ .width('100%')
177+ .padding(16)
178+ }
179+ .width('100%')
180+ .height('100%')
181+ }
182+}
@@ -0,0 +1,245 @@
1+/**
2+ * Copyright (c) 2026 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+import {
17+ DialogPresenter,
18+ DialogResult,
19+ ComponentContent,
20+ LengthMetrics,
21+ dialog,
22+} from '@kit.ArkUI';
23+ 
24+interface CustomParam {
25+ text: string;
26+}
27+ 
28+@Builder
29+function buildCustomDialog(param: CustomParam) {
30+ Column() {
31+ Text(param.text)
32+ .fontSize(18)
33+ .margin(12)
34+ .id('custom_dialog_text')
35+ Button('CustomClose')
36+ .id('custom_dialog_close')
37+ }
38+ .padding(16)
39+ .backgroundColor(Color.White)
40+}
41+ 
42+@Entry
43+@Component
44+struct DialogCustomPresent {
45+ @State lastAction: string = 'none';
46+ @State dialogId: number = -1;
47+ @State lastError: string = 'none';
48+ contentNode: ComponentContent<CustomParam> | null = null;
49+ 
50+ private presenter(): DialogPresenter {
51+ return this.getUIContext().getDialogPresenter();
52+ }
53+ 
54+ build() {
55+ Column({ space: 12 }) {
56+ Text('DialogCustomOptions present').fontSize(18).fontWeight(FontWeight.Bold)
57+ Text('action=' + this.lastAction).id('custom_present_action')
58+ Text('dialogId=' + this.dialogId).id('custom_present_dialog_id')
59+ Text('error=' + this.lastError).id('custom_present_error')
60+ Button('customStyle ComponentContent')
61+ .id('btn_custom_style_true')
62+ .onClick(async () => {
63+ this.lastError = 'none';
64+ try {
65+ let param: CustomParam = { text: 'CustomStyleContent' };
66+ this.contentNode = new ComponentContent(this.getUIContext(),
67+ wrapBuilder<[CustomParam]>(buildCustomDialog), param);
68+ let opts: dialog.DialogCustomOptions = {
69+ customStyle: true,
70+ width: 300,
71+ height: 180,
72+ backgroundColor: Color.Transparent,
73+ autoCancel: true,
74+ focusable: true,
75+ // 非 modal,便于用例点击页上 dismiss/update
76+ isModal: false,
77+ keyboardAvoidMode: KeyboardAvoidMode.DEFAULT,
78+ keyboardAvoidDistance: LengthMetrics.vp(8)
79+ };
80+ let result: DialogResult = await this.presenter().present(this.contentNode, opts);
81+ this.dialogId = result.dialogId;
82+ this.lastAction = 'customOpened';
83+ } catch (err) {
84+ this.lastError = String(err);
85+ this.lastAction = 'error';
86+ }
87+ })
88+ Button('ComponentContent custom')
89+ .id('btn_custom_content')
90+ .onClick(async () => {
91+ this.lastError = 'none';
92+ try {
93+ let param: CustomParam = { text: 'ComponentContentDialog' };
94+ this.contentNode = new ComponentContent(this.getUIContext(),
95+ wrapBuilder<[CustomParam]>(buildCustomDialog), param);
96+ let opts: dialog.DialogCustomOptions = {
97+ customStyle: false,
98+ width: '70%',
99+ height: 200,
100+ backgroundColor: Color.White,
101+ borderRadius: 8,
102+ isModal: false,
103+ autoCancel: true
104+ };
105+ let result: DialogResult = await this.presenter().present(this.contentNode, opts);
106+ this.dialogId = result.dialogId;
107+ this.lastAction = 'contentOpened';
108+ } catch (err) {
109+ this.lastError = String(err);
110+ this.lastAction = 'error';
111+ }
112+ })
113+ Button('dismiss by id')
114+ .id('btn_custom_dismiss')
115+ .onClick(async () => {
116+ try {
117+ if (this.dialogId >= 0) {
118+ await this.presenter().dismiss(this.dialogId);
119+ this.lastAction = 'dismissed';
120+ }
121+ } catch (err) {
122+ this.lastError = String(err);
123+ }
124+ })
125+ Button('update options')
126+ .id('btn_custom_update')
127+ .onClick(async () => {
128+ try {
129+ if (this.contentNode !== null) {
130+ let opts: dialog.DialogBaseOptions = {
131+ backgroundColor: '#E8F5E9',
132+ borderWidth: 3,
133+ borderColor: Color.Green
134+ };
135+ await this.presenter().update(this.contentNode, opts);
136+ this.lastAction = 'updated';
137+ }
138+ } catch (err) {
139+ this.lastError = String(err);
140+ }
141+ })
142+ Button('present then update')
143+ .id('btn_custom_present_update')
144+ .onClick(async () => {
145+ this.lastError = 'none';
146+ try {
147+ let param: CustomParam = { text: 'PresentUpdateContent' };
148+ this.contentNode = new ComponentContent(this.getUIContext(),
149+ wrapBuilder<[CustomParam]>(buildCustomDialog), param);
150+ let opts: dialog.DialogCustomOptions = {
151+ customStyle: false,
152+ width: 260,
153+ height: 150,
154+ backgroundColor: Color.White,
155+ isModal: false
156+ };
157+ let result: DialogResult = await this.presenter().present(this.contentNode, opts);
158+ this.dialogId = result.dialogId;
159+ let upd: dialog.DialogBaseOptions = {
160+ backgroundColor: '#E3F2FD',
161+ borderWidth: 2,
162+ borderColor: Color.Blue
163+ };
164+ await this.presenter().update(this.contentNode, upd);
165+ this.lastAction = 'updated';
166+ } catch (err) {
167+ this.lastError = String(err);
168+ this.lastAction = 'error';
169+ }
170+ })
171+ Button('custom width height')
172+ .id('btn_custom_size')
173+ .onClick(async () => {
174+ this.lastError = 'none';
175+ try {
176+ let param: CustomParam = { text: 'CustomSizeContent' };
177+ this.contentNode = new ComponentContent(this.getUIContext(),
178+ wrapBuilder<[CustomParam]>(buildCustomDialog), param);
179+ let opts: dialog.DialogCustomOptions = {
180+ customStyle: false,
181+ width: 280,
182+ height: 160,
183+ backgroundColor: '#FFF8E1',
184+ borderRadius: 16,
185+ isModal: false
186+ };
187+ let result: DialogResult = await this.presenter().present(this.contentNode, opts);
188+ this.dialogId = result.dialogId;
189+ this.lastAction = 'sizeOpened';
190+ } catch (err) {
191+ this.lastError = String(err);
192+ }
193+ })
194+ Button('custom border radius color')
195+ .id('btn_custom_border')
196+ .onClick(async () => {
197+ this.lastError = 'none';
198+ try {
199+ let param: CustomParam = { text: 'CustomBorderContent' };
200+ this.contentNode = new ComponentContent(this.getUIContext(),
201+ wrapBuilder<[CustomParam]>(buildCustomDialog), param);
202+ let opts: dialog.DialogCustomOptions = {
203+ customStyle: false,
204+ borderWidth: 2,
205+ borderColor: Color.Blue,
206+ borderRadius: 24,
207+ backgroundColor: Color.White,
208+ isModal: false
209+ };
210+ let result: DialogResult = await this.presenter().present(this.contentNode, opts);
211+ this.dialogId = result.dialogId;
212+ this.lastAction = 'borderOpened';
213+ } catch (err) {
214+ this.lastError = String(err);
215+ }
216+ })
217+ Button('custom autoCancel focusable')
218+ .id('btn_custom_flags')
219+ .onClick(async () => {
220+ this.lastError = 'none';
221+ try {
222+ let param: CustomParam = { text: 'CustomFlagsContent' };
223+ this.contentNode = new ComponentContent(this.getUIContext(),
224+ wrapBuilder<[CustomParam]>(buildCustomDialog), param);
225+ let opts: dialog.DialogCustomOptions = {
226+ customStyle: false,
227+ autoCancel: false,
228+ focusable: true,
229+ isModal: false,
230+ backgroundColor: Color.White
231+ };
232+ let result: DialogResult = await this.presenter().present(this.contentNode, opts);
233+ this.dialogId = result.dialogId;
234+ this.lastAction = 'flagsOpened';
235+ } catch (err) {
236+ this.lastError = String(err);
237+ }
238+ })
239+ }
240+ .width('100%')
241+ .height('100%')
242+ .padding(16)
243+ .justifyContent(FlexAlign.Center)
244+ }
245+}
@@ -0,0 +1,98 @@
1+/**
2+ * Copyright (c) 2026 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+import {
17+ DialogState,
18+ DialogBaseAlignment,
19+ DialogButtonOrientation,
20+} from '@kit.ArkUI';
21+ 
22+@Entry
23+@Component
24+struct DialogEnumsAssert {
25+ @State resultText: string = 'idle';
26+ 
27+ private setResult(ok: boolean, detail: string): void {
28+ this.resultText = (ok ? 'PASS:' : 'FAIL:') + detail;
29+ }
30+ 
31+ build() {
32+ Column({ space: 6 }) {
33+ Text('dialog enums part1').fontSize(16).fontWeight(FontWeight.Bold)
34+ Text(this.resultText).id('enums_result').fontSize(14)
35+ Button('DialogState values').id('btn_enum_state').onClick(() => {
36+ let ok = DialogState.UNINITIALIZED === 0 && DialogState.INITIALIZED === 1 &&
37+ DialogState.APPEARING === 2 && DialogState.APPEARED === 3 &&
38+ DialogState.DISAPPEARING === 4 && DialogState.DISAPPEARED === 5;
39+ this.setResult(ok, 'DialogState');
40+ })
41+ Button('DialogBaseAlignment values').id('btn_enum_align').onClick(() => {
42+ let ok = DialogBaseAlignment.TOP === 0 && DialogBaseAlignment.CENTER === 1 &&
43+ DialogBaseAlignment.BOTTOM === 2 && DialogBaseAlignment.DEFAULT === 3 &&
44+ DialogBaseAlignment.TOP_START === 4 && DialogBaseAlignment.TOP_END === 5 &&
45+ DialogBaseAlignment.CENTER_START === 6 && DialogBaseAlignment.CENTER_END === 7 &&
46+ DialogBaseAlignment.BOTTOM_START === 8 && DialogBaseAlignment.BOTTOM_END === 9;
47+ this.setResult(ok, 'DialogBaseAlignment');
48+ })
49+ Button('DialogButtonOrientation values').id('btn_enum_btn_orient').onClick(() => {
50+ let ok = DialogButtonOrientation.AUTO === 0 &&
51+ DialogButtonOrientation.HORIZONTAL === 1 &&
52+ DialogButtonOrientation.VERTICAL === 2;
53+ this.setResult(ok, 'DialogButtonOrientation');
54+ })
55+ Button('all enums batch').id('btn_enum_all').onClick(() => {
56+ let ok = DialogState.APPEARED === 3 && DialogBaseAlignment.CENTER === 1 &&
57+ DialogButtonOrientation.HORIZONTAL === 1;
58+ this.setResult(ok, 'AllEnums');
59+ })
60+ Button('state UNINITIALIZED').id('btn_enum_state_0').onClick(() => {
61+ this.setResult(DialogState.UNINITIALIZED === 0, 'UNINITIALIZED');
62+ })
63+ Button('state INITIALIZED').id('btn_enum_state_1').onClick(() => {
64+ this.setResult(DialogState.INITIALIZED === 1, 'INITIALIZED');
65+ })
66+ Button('state APPEARING').id('btn_enum_state_2').onClick(() => {
67+ this.setResult(DialogState.APPEARING === 2, 'APPEARING');
68+ })
69+ Button('state APPEARED').id('btn_enum_state_3').onClick(() => {
70+ this.setResult(DialogState.APPEARED === 3, 'APPEARED');
71+ })
72+ Button('state DISAPPEARING').id('btn_enum_state_4').onClick(() => {
73+ this.setResult(DialogState.DISAPPEARING === 4, 'DISAPPEARING');
74+ })
75+ Button('state DISAPPEARED').id('btn_enum_state_5').onClick(() => {
76+ this.setResult(DialogState.DISAPPEARED === 5, 'DISAPPEARED');
77+ })
78+ Button('align TOP').id('btn_enum_align_0').onClick(() => {
79+ this.setResult(DialogBaseAlignment.TOP === 0, 'TOP');
80+ })
81+ Button('align CENTER').id('btn_enum_align_1').onClick(() => {
82+ this.setResult(DialogBaseAlignment.CENTER === 1, 'CENTER');
83+ })
84+ Button('align BOTTOM').id('btn_enum_align_2').onClick(() => {
85+ this.setResult(DialogBaseAlignment.BOTTOM === 2, 'BOTTOM');
86+ })
87+ Button('align DEFAULT').id('btn_enum_align_3').onClick(() => {
88+ this.setResult(DialogBaseAlignment.DEFAULT === 3, 'DEFAULT');
89+ })
90+ Button('align TOP_START').id('btn_enum_align_4').onClick(() => {
91+ this.setResult(DialogBaseAlignment.TOP_START === 4, 'TOP_START');
92+ })
93+ }
94+ .width('100%')
95+ .height('100%')
96+ .padding(12)
97+ }
98+}
@@ -0,0 +1,71 @@
1+/**
2+ * Copyright (c) 2026 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+import {
17+ DialogBaseAlignment,
18+ DialogButtonOrientation,
19+ dialog,
20+} from '@kit.ArkUI';
21+ 
22+@Entry
23+@Component
24+struct DialogEnumsAssertExtra {
25+ @State resultText: string = 'idle';
26+ 
27+ private setResult(ok: boolean, detail: string): void {
28+ this.resultText = (ok ? 'PASS:' : 'FAIL:') + detail;
29+ }
30+ 
31+ build() {
32+ Column({ space: 6 }) {
33+ Text('dialog enums part2').fontSize(16).fontWeight(FontWeight.Bold)
34+ Text(this.resultText).id('enums_extra_result').fontSize(14)
35+ Button('align TOP_END').id('btn_enum_align_5').onClick(() => {
36+ this.setResult(DialogBaseAlignment.TOP_END === 5, 'TOP_END');
37+ })
38+ Button('align CENTER_START').id('btn_enum_align_6').onClick(() => {
39+ this.setResult(DialogBaseAlignment.CENTER_START === 6, 'CENTER_START');
40+ })
41+ Button('align CENTER_END').id('btn_enum_align_7').onClick(() => {
42+ this.setResult(DialogBaseAlignment.CENTER_END === 7, 'CENTER_END');
43+ })
44+ Button('align BOTTOM_START').id('btn_enum_align_8').onClick(() => {
45+ this.setResult(DialogBaseAlignment.BOTTOM_START === 8, 'BOTTOM_START');
46+ })
47+ Button('align BOTTOM_END').id('btn_enum_align_9').onClick(() => {
48+ this.setResult(DialogBaseAlignment.BOTTOM_END === 9, 'BOTTOM_END');
49+ })
50+ Button('orient AUTO').id('btn_enum_orient_0').onClick(() => {
51+ this.setResult(DialogButtonOrientation.AUTO === 0, 'AUTO');
52+ })
53+ Button('orient HORIZONTAL').id('btn_enum_orient_1').onClick(() => {
54+ this.setResult(DialogButtonOrientation.HORIZONTAL === 1, 'HORIZONTAL');
55+ })
56+ Button('orient VERTICAL').id('btn_enum_orient_2').onClick(() => {
57+ this.setResult(DialogButtonOrientation.VERTICAL === 2, 'VERTICAL');
58+ })
59+ Button('DialogTextStyleOptions cover').id('btn_enum_text_style').onClick(() => {
60+ let msg: dialog.DialogMessage = {
61+ content: 'TextStyleCover',
62+ wordBreak: WordBreak.BREAK_ALL
63+ };
64+ this.setResult(msg.wordBreak === WordBreak.BREAK_ALL, 'DialogTextStyleOptions');
65+ })
66+ }
67+ .width('100%')
68+ .height('100%')
69+ .padding(12)
70+ }
71+}
@@ -0,0 +1,178 @@
1+/**
2+ * Copyright (c) 2026 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+import { DialogPresenter, DialogDismissal } from '@kit.ArkUI';
17+ 
18+@Entry
19+@Component
20+struct DialogLifeCallbacks {
21+ @State lastAction: string = 'none';
22+ @State lifeLog: string = '';
23+ 
24+ private presenter(): DialogPresenter {
25+ return this.getUIContext().getDialogPresenter();
26+ }
27+ 
28+ private append(tag: string): void {
29+ this.lifeLog = this.lifeLog + tag + ';';
30+ }
31+ 
32+ build() {
33+ Scroll() {
34+ Column({ space: 8 }) {
35+ Text('DialogBaseOptions lifecycle callbacks').fontSize(18).fontWeight(FontWeight.Bold)
36+ Text('action=' + this.lastAction).id('life_cb_action')
37+ Text('life=' + this.lifeLog).id('life_cb_log')
38+ Button('onWillAppear')
39+ .id('btn_life_will_appear')
40+ .onClick(async () => {
41+ this.lifeLog = '';
42+ await this.presenter().present({
43+ title: 'WillAppearTitle',
44+ message: { content: 'WillAppearMsg' },
45+ onWillAppear: () => {
46+ this.append('willAppear');
47+ this.lastAction = 'willAppear';
48+ },
49+ buttons: [{
50+ value: 'WillAppearOK',
51+ action: () => { this.lastAction = 'WillAppearOK'; }
52+ }]
53+ });
54+ })
55+ Button('onDidAppear')
56+ .id('btn_life_did_appear')
57+ .onClick(async () => {
58+ this.lifeLog = '';
59+ await this.presenter().present({
60+ title: 'DidAppearTitle',
61+ message: { content: 'DidAppearMsg' },
62+ onDidAppear: () => {
63+ this.append('didAppear');
64+ this.lastAction = 'didAppear';
65+ },
66+ buttons: [{
67+ value: 'DidAppearOK',
68+ action: () => { this.lastAction = 'DidAppearOK'; }
69+ }]
70+ });
71+ })
72+ Button('onWillDisappear')
73+ .id('btn_life_will_disappear')
74+ .onClick(async () => {
75+ this.lifeLog = '';
76+ await this.presenter().present({
77+ title: 'WillDisappearTitle',
78+ message: { content: 'WillDisappearMsg' },
79+ onWillDisappear: () => {
80+ this.append('willDisappear');
81+ this.lastAction = 'willDisappear';
82+ },
83+ buttons: [{
84+ value: 'WillDisappearOK',
85+ action: () => { this.lastAction = 'WillDisappearOK'; }
86+ }]
87+ });
88+ })
89+ Button('onDidDisappear')
90+ .id('btn_life_did_disappear')
91+ .onClick(async () => {
92+ this.lifeLog = '';
93+ await this.presenter().present({
94+ title: 'DidDisappearTitle',
95+ message: { content: 'DidDisappearMsg' },
96+ onDidDisappear: () => {
97+ this.append('didDisappear');
98+ this.lastAction = 'didDisappear';
99+ },
100+ buttons: [{
101+ value: 'DidDisappearOK',
102+ action: () => { this.lastAction = 'DidDisappearOK'; }
103+ }]
104+ });
105+ })
106+ Button('full life chain')
107+ .id('btn_life_full')
108+ .onClick(async () => {
109+ this.lifeLog = '';
110+ await this.presenter().present({
111+ title: 'FullLifeTitle',
112+ message: { content: 'FullLifeMsg' },
113+ onWillAppear: () => { this.append('W'); },
114+ onDidAppear: () => { this.append('D'); },
115+ onWillDisappear: () => { this.append('w'); },
116+ onDidDisappear: () => {
117+ this.append('d');
118+ this.lastAction = 'fullLife';
119+ },
120+ buttons: [{
121+ value: 'FullLifeOK',
122+ action: () => { this.lastAction = 'FullLifeOK'; }
123+ }]
124+ });
125+ })
126+ Button('onWillDismiss reason')
127+ .id('btn_life_will_dismiss')
128+ .onClick(async () => {
129+ this.lifeLog = '';
130+ await this.presenter().present({
131+ title: 'DismissLifeTitle',
132+ message: { content: 'DismissLifeMsg' },
133+ autoCancel: true,
134+ onWillDismiss: (dismissal: DialogDismissal) => {
135+ this.lifeLog = 'reason=' + String(dismissal.reason);
136+ this.lastAction = 'dismissCb';
137+ dismissal.dismiss();
138+ },
139+ buttons: [{
140+ value: 'DismissLifeOK',
141+ action: () => { this.lastAction = 'DismissLifeOK'; }
142+ }]
143+ });
144+ })
145+ Button('subtitle only style')
146+ .id('btn_life_subtitle')
147+ .onClick(async () => {
148+ await this.presenter().present({
149+ title: 'SubOnlyTitle',
150+ subtitle: 'OnlySubtitle',
151+ message: { content: 'SubOnlyMsg' },
152+ buttons: [{
153+ value: 'SubOnlyOK',
154+ action: () => { this.lastAction = 'SubOnlyOK'; }
155+ }]
156+ });
157+ })
158+ Button('title subtitle message')
159+ .id('btn_life_tsm')
160+ .onClick(async () => {
161+ await this.presenter().present({
162+ title: 'TSMTitle',
163+ subtitle: 'TSMSub',
164+ message: { content: 'TSMMsg', wordBreak: WordBreak.BREAK_ALL },
165+ buttons: [{
166+ value: 'TSMOK',
167+ action: () => { this.lastAction = 'TSMOK'; }
168+ }]
169+ });
170+ })
171+ }
172+ .width('100%')
173+ .padding(16)
174+ }
175+ .width('100%')
176+ .height('100%')
177+ }
178+}
@@ -0,0 +1,245 @@
1+/**
2+ * Copyright (c) 2026 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+import {
17+ DialogPresenter,
18+ DialogButtonOrientation,
19+ DialogResult,
20+} from '@kit.ArkUI';
21+ 
22+@Entry
23+@Component
24+struct DialogStyleAlert {
25+ @State lastAction: string = 'none';
26+ @State lastDialogId: number = -1;
27+ @State lifeLog: string = '';
28+ 
29+ private appendLife(tag: string): void {
30+ this.lifeLog = this.lifeLog + tag + ';';
31+ }
32+ 
33+ private presenter(): DialogPresenter {
34+ return this.getUIContext().getDialogPresenter();
35+ }
36+ 
37+ build() {
38+ Scroll() {
39+ Column({ space: 10 }) {
40+ Text('DialogStyleOptions alert').fontSize(18).fontWeight(FontWeight.Bold)
41+ Text('action=' + this.lastAction).id('style_alert_action')
42+ Text('dialogId=' + this.lastDialogId).id('style_alert_dialog_id')
43+ Text('life=' + this.lifeLog).id('style_alert_life')
44+ Button('basic title message buttons')
45+ .id('btn_style_alert_basic')
46+ .onClick(async () => {
47+ this.lifeLog = '';
48+ let result: DialogResult = await this.presenter().present({
49+ title: 'AlertTitle',
50+ subtitle: 'AlertSub',
51+ message: { content: 'AlertMessage', wordBreak: WordBreak.BREAK_WORD },
52+ buttons: [
53+ {
54+ value: 'AlertCancel',
55+ fontColor: Color.Gray,
56+ backgroundColor: Color.White,
57+ enabled: true,
58+ defaultFocus: false,
59+ primary: false,
60+ style: DialogButtonStyle.DEFAULT,
61+ action: () => {
62+ this.lastAction = 'AlertCancel';
63+ }
64+ },
65+ {
66+ value: 'AlertOK',
67+ fontColor: Color.White,
68+ backgroundColor: Color.Blue,
69+ enabled: true,
70+ defaultFocus: true,
71+ primary: true,
72+ style: DialogButtonStyle.HIGHLIGHT,
73+ action: () => {
74+ this.lastAction = 'AlertOK';
75+ }
76+ }
77+ ],
78+ buttonDirection: DialogButtonOrientation.HORIZONTAL,
79+ onWillAppear: () => {
80+ this.appendLife('willAppear');
81+ },
82+ onDidAppear: () => {
83+ this.appendLife('didAppear');
84+ },
85+ onWillDisappear: () => {
86+ this.appendLife('willDisappear');
87+ },
88+ onDidDisappear: () => {
89+ this.appendLife('didDisappear');
90+ }
91+ });
92+ this.lastDialogId = result.dialogId;
93+ })
94+ Button('vertical buttons')
95+ .id('btn_style_alert_vertical')
96+ .onClick(async () => {
97+ await this.presenter().present({
98+ title: 'VerticalTitle',
99+ message: { content: 'VerticalMessage' },
100+ buttonDirection: DialogButtonOrientation.VERTICAL,
101+ buttons: [
102+ {
103+ value: 'VertA',
104+ action: () => {
105+ this.lastAction = 'VertA';
106+ }
107+ },
108+ {
109+ value: 'VertB',
110+ action: () => {
111+ this.lastAction = 'VertB';
112+ }
113+ },
114+ {
115+ value: 'VertC',
116+ action: () => {
117+ this.lastAction = 'VertC';
118+ }
119+ }
120+ ]
121+ });
122+ })
123+ Button('auto orientation')
124+ .id('btn_style_alert_auto')
125+ .onClick(async () => {
126+ await this.presenter().present({
127+ title: 'AutoTitle',
128+ message: { content: 'AutoMessage' },
129+ buttonDirection: DialogButtonOrientation.AUTO,
130+ buttons: [
131+ {
132+ value: 'AutoOK',
133+ enabled: true,
134+ action: () => {
135+ this.lastAction = 'AutoOK';
136+ }
137+ }
138+ ]
139+ });
140+ })
141+ Button('disabled button')
142+ .id('btn_style_alert_disabled')
143+ .onClick(async () => {
144+ await this.presenter().present({
145+ title: 'DisableTitle',
146+ message: { content: 'DisableMessage' },
147+ buttons: [
148+ {
149+ value: 'DisabledBtn',
150+ enabled: false,
151+ action: () => {
152+ this.lastAction = 'DisabledBtn';
153+ }
154+ },
155+ {
156+ value: 'EnableOK',
157+ enabled: true,
158+ action: () => {
159+ this.lastAction = 'EnableOK';
160+ }
161+ }
162+ ]
163+ });
164+ })
165+ Button('wordBreak NORMAL')
166+ .id('btn_style_alert_wordbreak')
167+ .onClick(async () => {
168+ await this.presenter().present({
169+ title: 'WordBreakTitle',
170+ message: {
171+ content: 'WordBreakNormalMessageContentLong',
172+ wordBreak: WordBreak.NORMAL
173+ },
174+ buttons: [
175+ {
176+ value: 'WBClose',
177+ action: () => {
178+ this.lastAction = 'WBClose';
179+ }
180+ }
181+ ]
182+ });
183+ })
184+ Button('wordBreak BREAK_ALL')
185+ .id('btn_style_alert_wb_all')
186+ .onClick(async () => {
187+ await this.presenter().present({
188+ title: 'WBAllTitle',
189+ message: {
190+ content: 'WBAllLongMessageContentForBreak',
191+ wordBreak: WordBreak.BREAK_ALL
192+ },
193+ buttons: [
194+ {
195+ value: 'WBAllOK',
196+ action: () => {
197+ this.lastAction = 'WBAllOK';
198+ }
199+ }
200+ ]
201+ });
202+ })
203+ Button('subtitle field')
204+ .id('btn_style_alert_subtitle')
205+ .onClick(async () => {
206+ await this.presenter().present({
207+ title: 'SubTitleMain',
208+ subtitle: 'SubTitleValue',
209+ message: { content: 'SubTitleMsg' },
210+ buttons: [
211+ {
212+ value: 'SubTitleOK',
213+ action: () => {
214+ this.lastAction = 'SubTitleOK';
215+ }
216+ }
217+ ]
218+ });
219+ })
220+ Button('dialogId result')
221+ .id('btn_style_alert_dialogid')
222+ .onClick(async () => {
223+ let result: DialogResult = await this.presenter().present({
224+ title: 'DialogIdTitle',
225+ message: { content: 'DialogIdMsg' },
226+ buttons: [
227+ {
228+ value: 'DialogIdOK',
229+ action: () => {
230+ this.lastAction = 'DialogIdOK';
231+ }
232+ }
233+ ]
234+ });
235+ this.lastDialogId = result.dialogId;
236+ this.lastAction = 'dialogId=' + result.dialogId;
237+ })
238+ }
239+ .width('100%')
240+ .padding(16)
241+ }
242+ .width('100%')
243+ .height('100%')
244+ }
245+}