1/* 2 * Copyright (c) 2023 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/// <reference path='./import.ts' /> 17const TITLE_MODE_RANGE = 2; 18const NAV_BAR_POSITION_RANGE = 1; 19const NAVIGATION_MODE_RANGE = 2; 20const DEFAULT_NAV_BAR_WIDTH = 240; 21const MIN_NAV_BAR_WIDTH_DEFAULT = '240vp'; 22const MAX_NAV_BAR_WIDTH_DEFAULT = '40%'; 23const NAVIGATION_TITLE_MODE_DEFAULT = 0; 24const DEFAULT_UNIT = 'vp'; 25const NAV_SAFE_AREA_TYPE_LIMIT = 3; 26const NAV_SAFE_AREA_EDGE_LIMIT = 4; 27const NAV_SAFE_AREA_LOWER_LIMIT = 0; 28 29class ArkNavigationComponent extends ArkComponent implements NavigationAttribute { 30 constructor(nativePtr: KNode, classType?: ModifierType) { 31 super(nativePtr, classType); 32 } 33 navBarWidth(value: Length): NavigationAttribute { 34 modifierWithKey(this._modifiersWithKeys, NavBarWidthModifier.identity, NavBarWidthModifier, value); 35 return this; 36 } 37 navBarPosition(value: number): NavigationAttribute { 38 modifierWithKey(this._modifiersWithKeys, NavBarPositionModifier.identity, NavBarPositionModifier, value); 39 return this; 40 } 41 navBarWidthRange(value: [Dimension, Dimension]): NavigationAttribute { 42 modifierWithKey(this._modifiersWithKeys, NavBarWidthRangeModifier.identity, NavBarWidthRangeModifier, value); 43 return this; 44 } 45 minContentWidth(value: Dimension): NavigationAttribute { 46 modifierWithKey(this._modifiersWithKeys, MinContentWidthModifier.identity, MinContentWidthModifier, value); 47 48 return this; 49 } 50 mode(value: number): NavigationAttribute { 51 modifierWithKey(this._modifiersWithKeys, ModeModifier.identity, ModeModifier, value); 52 return this; 53 } 54 backButtonIcon(value: any): NavigationAttribute { 55 modifierWithKey(this._modifiersWithKeys, BackButtonIconModifier.identity, BackButtonIconModifier, value); 56 return this; 57 } 58 hideNavBar(value: boolean): NavigationAttribute { 59 modifierWithKey(this._modifiersWithKeys, HideNavBarModifier.identity, HideNavBarModifier, value); 60 return this; 61 } 62 title(value: ResourceStr | CustomBuilder | NavigationCommonTitle | NavigationCustomTitle | undefined, 63 options?: NavigationTitleOptions): NavigationAttribute { 64 if (isUndefined(value) || isNull(value)) { 65 modifierWithKey(this._modifiersWithKeys, TitleModifier.identity, 66 TitleModifier, undefined); 67 return this; 68 } 69 let arkNavigationTitle = new ArkNavigationTitle(); 70 arkNavigationTitle.value = value; 71 if (!isUndefined(options) && !isNull(options) && isObject(options)) { 72 if (Object.keys(options).length !== 0) { 73 arkNavigationTitle.navigationTitleOptions = options; 74 } 75 } 76 modifierWithKey(this._modifiersWithKeys, TitleModifier.identity, 77 TitleModifier, arkNavigationTitle); 78 return this; 79 } 80 subTitle(value: string): NavigationAttribute { 81 modifierWithKey(this._modifiersWithKeys, SubTitleModifier.identity, SubTitleModifier, value); 82 return this; 83 } 84 enableModeChangeAnimation(value: boolean): NavigationAttribute { 85 modifierWithKey(this._modifiersWithKeys, EnableModeChangeAnimationModifier.identity, EnableModeChangeAnimationModifier, value); 86 return this; 87 } 88 hideTitleBar(isHide: boolean, animated?: boolean): NavigationAttribute { 89 let arkNavigationHideTitleBar = new ArkNavHideTitleBarOrToolBar(); 90 if (!isUndefined(isHide) && !isNull(isHide)) { 91 arkNavigationHideTitleBar.isHide = isHide; 92 } 93 if (!isUndefined(animated) && !isNull(animated)) { 94 arkNavigationHideTitleBar.animated = animated; 95 } 96 if (arkNavigationHideTitleBar.isHide === undefined && arkNavigationHideTitleBar.animated === undefined) { 97 modifierWithKey(this._modifiersWithKeys, NavigationHideTitleBarModifier.identity, NavigationHideTitleBarModifier, undefined); 98 } else { 99 modifierWithKey(this._modifiersWithKeys, NavigationHideTitleBarModifier.identity, NavigationHideTitleBarModifier, arkNavigationHideTitleBar); 100 } 101 return this; 102 } 103 hideBackButton(value: boolean): NavigationAttribute { 104 modifierWithKey(this._modifiersWithKeys, HideBackButtonModifier.identity, HideBackButtonModifier, value); 105 return this; 106 } 107 titleMode(value: NavigationTitleMode): NavigationAttribute { 108 modifierWithKey(this._modifiersWithKeys, TitleModeModifier.identity, TitleModeModifier, value); 109 return this; 110 } 111 menus(value: Array<NavigationMenuItem> | undefined): NavigationAttribute { 112 if (isUndefined(value)) { 113 modifierWithKey(this._modifiersWithKeys, MenusModifier.identity, MenusModifier, undefined); 114 return this; 115 } 116 modifierWithKey(this._modifiersWithKeys, MenusModifier.identity, MenusModifier, value); 117 return this; 118 } 119 toolBar(value: any): NavigationAttribute { 120 throw new Error('Method not implemented.'); 121 } 122 toolbarConfiguration(value: any): NavigationAttribute { 123 throw new Error('Method not implemented.'); 124 } 125 hideToolBar(isHide: boolean, animated?: boolean): NavigationAttribute { 126 let arkNavigationHideToolBar = new ArkNavHideTitleBarOrToolBar(); 127 if (!isUndefined(isHide) && !isNull(isHide)) { 128 arkNavigationHideToolBar.isHide = isHide; 129 } 130 if (!isUndefined(animated) && !isNull(animated)) { 131 arkNavigationHideToolBar.animated = animated; 132 } 133 if (arkNavigationHideToolBar.isHide === undefined && arkNavigationHideToolBar.animated === undefined) { 134 modifierWithKey(this._modifiersWithKeys, HideToolBarModifier.identity, HideToolBarModifier, undefined); 135 } else { 136 modifierWithKey(this._modifiersWithKeys, HideToolBarModifier.identity, HideToolBarModifier, arkNavigationHideToolBar); 137 } 138 return this; 139 } 140 onTitleModeChange(callback: (titleMode: NavigationTitleMode) => void): NavigationAttribute { 141 throw new Error('Method not implemented.'); 142 } 143 onNavBarStateChange(callback: (isVisible: boolean) => void): NavigationAttribute { 144 throw new Error('Method not implemented.'); 145 } 146 onNavigationModeChange(callback: (mode: NavigationMode) => void): NavigationAttribute { 147 throw new Error('Method not implemented.'); 148 } 149 navDestination(builder: (name: string, param: unknown) => void): NavigationAttribute { 150 throw new Error('Method not implemented.'); 151 } 152 ignoreLayoutSafeArea(types?: Array<SafeAreaType>, edges?: Array<SafeAreaEdge>): NavigationAttribute { 153 let opts = new ArkSafeAreaExpandOpts(); 154 if (types && types.length >= 0) { 155 let safeAreaType: string | number = ''; 156 for (let param of types) { 157 if (!isNumber(param) || param >= NAV_SAFE_AREA_TYPE_LIMIT || param < NAV_SAFE_AREA_LOWER_LIMIT) { 158 safeAreaType = undefined; 159 break; 160 } 161 if (safeAreaType) { 162 safeAreaType += '|'; 163 safeAreaType += param.toString(); 164 } else { 165 safeAreaType += param.toString(); 166 } 167 } 168 opts.type = safeAreaType; 169 } 170 if (edges && edges.length >= 0) { 171 let safeAreaEdge: string | number = ''; 172 for (let param of edges) { 173 if (!isNumber(param) || param >= NAV_SAFE_AREA_EDGE_LIMIT || param < NAV_SAFE_AREA_LOWER_LIMIT) { 174 safeAreaEdge = undefined; 175 break; 176 } 177 if (safeAreaEdge) { 178 safeAreaEdge += '|'; 179 safeAreaEdge += param.toString(); 180 } else { 181 safeAreaEdge += param.toString(); 182 } 183 } 184 opts.edges = safeAreaEdge; 185 } 186 if (opts.type === undefined && opts.edges === undefined) { 187 modifierWithKey(this._modifiersWithKeys, IgnoreNavLayoutSafeAreaModifier.identity, IgnoreNavLayoutSafeAreaModifier, undefined); 188 } else { 189 modifierWithKey(this._modifiersWithKeys, IgnoreNavLayoutSafeAreaModifier.identity, IgnoreNavLayoutSafeAreaModifier, opts); 190 } 191 return this; 192 } 193 194 enableDargBar(value: boolean | undefined): NavigationAttribute { 195 modifierWithKey(this._modifiersWithKeys, NavigationEnableDragBarModifier.identity, NavigationEnableDragBarModifier, value); 196 return this; 197 } 198 recoverable(value: boolean | undefined): NavigationAttribute { 199 modifierWithKey(this._modifiersWithKeys, NavigationRecoverableModifier.identity, NavigationRecoverableModifier, value); 200 return this; 201 } 202} 203 204class BackButtonIconModifier extends ModifierWithKey<boolean | object> { 205 static identity: Symbol = Symbol('backButtonIcon'); 206 applyPeer(node: KNode, reset: boolean): void { 207 if (reset) { 208 getUINativeModule().navigation.resetBackButtonIcon(node); 209 } else { 210 getUINativeModule().navigation.setBackButtonIcon(node, this.value); 211 } 212 } 213 214 checkObjectDiff(): boolean { 215 return !isBaseOrResourceEqual(this.stageValue, this.value); 216 } 217} 218 219class NavBarWidthRangeModifier extends ModifierWithKey<[Dimension, Dimension]> { 220 static identity: Symbol = Symbol('navBarWidthRange'); 221 applyPeer(node: KNode, reset: boolean): void { 222 if (reset) { 223 getUINativeModule().navigation.resetNavBarWidthRange(node); 224 } else { 225 getUINativeModule().navigation.setNavBarWidthRange(node, this.value); 226 } 227 } 228 229 checkObjectDiff(): boolean { 230 return !isBaseOrResourceEqual(this.stageValue, this.value); 231 } 232} 233 234class MinContentWidthModifier extends ModifierWithKey<Dimension> { 235 static identity: Symbol = Symbol('minContentWidth'); 236 237 applyPeer(node: KNode, reset: boolean): void { 238 if (reset) { 239 getUINativeModule().navigation.resetMinContentWidth(node); 240 } else { 241 getUINativeModule().navigation.setMinContentWidth(node, this.value); 242 } 243 } 244 245 checkObjectDiff(): boolean { 246 return !isBaseOrResourceEqual(this.stageValue, this.value); 247 } 248} 249 250class NavBarWidthModifier extends ModifierWithKey<Length> { 251 static identity: Symbol = Symbol('navBarWidth'); 252 253 applyPeer(node: KNode, reset: boolean): void { 254 if (reset) { 255 getUINativeModule().navigation.resetNavBarWidth(node); 256 } else { 257 getUINativeModule().navigation.setNavBarWidth(node, this.value); 258 } 259 } 260 261 checkObjectDiff(): boolean { 262 return !isBaseOrResourceEqual(this.stageValue, this.value); 263 } 264} 265 266class NavBarPositionModifier extends ModifierWithKey<number> { 267 static identity: Symbol = Symbol('navBarPosition'); 268 269 applyPeer(node: KNode, reset: boolean): void { 270 if (reset) { 271 getUINativeModule().navigation.resetNavBarPosition(node); 272 } else { 273 getUINativeModule().navigation.setNavBarPosition(node, this.value); 274 } 275 } 276} 277 278class ModeModifier extends ModifierWithKey<number> { 279 static identity: Symbol = Symbol('mode'); 280 281 applyPeer(node: KNode, reset: boolean): void { 282 if (reset) { 283 getUINativeModule().navigation.resetMode(node); 284 } else { 285 getUINativeModule().navigation.setMode(node, this.value); 286 } 287 } 288} 289 290class HideToolBarModifier extends ModifierWithKey<ArkNavHideTitleBarOrToolBar | undefined> { 291 constructor(value: ArkNavHideTitleBarOrToolBar) { 292 super(value); 293 } 294 295 static identity: Symbol = Symbol('hideToolBar'); 296 297 applyPeer(node: KNode, reset: boolean): void { 298 if (reset) { 299 getUINativeModule().navigation.resetHideToolBar(node); 300 } else { 301 getUINativeModule().navigation.setHideToolBar(node, this.value?.isHide, this.value?.animated); 302 } 303 } 304} 305 306class TitleModeModifier extends ModifierWithKey<number> { 307 static identity: Symbol = Symbol('titleMode'); 308 309 applyPeer(node: KNode, reset: boolean): void { 310 if (reset) { 311 getUINativeModule().navigation.resetTitleMode(node); 312 } else { 313 getUINativeModule().navigation.setTitleMode(node, this.value); 314 } 315 } 316} 317 318class MenusModifier extends ModifierWithKey<Array<NavigationMenuItem> | undefined> { 319 constructor(value: Array<NavigationMenuItem> | undefined) { 320 super(value); 321 } 322 static identity: Symbol = Symbol('menus'); 323 324 applyPeer(node: KNode, reset: boolean): void { 325 if (reset) { 326 getUINativeModule().navigation.resetMenus(node); 327 } else { 328 getUINativeModule().navigation.setMenus(node, this.value); 329 } 330 } 331 332 checkObjectDiff(): boolean { 333 if (!Array.isArray(this.value) || !Array.isArray(this.stageValue)) { 334 return true; 335 } 336 if (this.value.length !== this.stageValue.length) { 337 return true; 338 } 339 for (let i = 0; i < this.value.length; i++) { 340 if (!(isBaseOrResourceEqual(this.stageValue[i].value, this.value[i].value) && 341 isBaseOrResourceEqual(this.stageValue[i].icon, this.value[i].icon) && 342 isBaseOrResourceEqual(this.stageValue[i].isEnabled, this.value[i].isEnabled) && 343 isBaseOrResourceEqual(this.stageValue[i].action, this.value[i].action) && 344 isBaseOrResourceEqual(this.stageValue[i].symbolIcon, this.value[i].symbolIcon) 345 )) { 346 return true; 347 } 348 } 349 return false; 350 } 351} 352 353class HideBackButtonModifier extends ModifierWithKey<boolean> { 354 static identity: Symbol = Symbol('hideBackButton'); 355 356 applyPeer(node: KNode, reset: boolean): void { 357 if (reset) { 358 getUINativeModule().navigation.resetHideBackButton(node); 359 } else { 360 getUINativeModule().navigation.setHideBackButton(node, this.value); 361 } 362 } 363} 364 365class TitleModifier extends ModifierWithKey<ArkNavigationTitle | undefined> { 366 constructor(value: ArkNavigationTitle | undefined) { 367 super(value); 368 } 369 static identity: Symbol = Symbol('title'); 370 applyPeer(node: KNode, reset: boolean): void { 371 if (reset) { 372 getUINativeModule().navigation.resetTitle(node); 373 } else { 374 getUINativeModule().navigation.setTitle(node, this.value?.value, this.value?.navigationTitleOptions); 375 } 376 } 377 checkObjectDiff(): boolean { 378 return !this.value.isEqual(this.stageValue); 379 } 380} 381 382class SubTitleModifier extends ModifierWithKey<string> { 383 static identity: Symbol = Symbol('subTitle'); 384 385 applyPeer(node: KNode, reset: boolean): void { 386 if (reset) { 387 getUINativeModule().navigation.resetSubTitle(node); 388 } else { 389 getUINativeModule().navigation.setSubTitle(node, this.value); 390 } 391 } 392} 393 394class NavigationHideTitleBarModifier extends ModifierWithKey<ArkNavHideTitleBarOrToolBar | undefined> { 395 constructor(value: ArkNavHideTitleBarOrToolBar) { 396 super(value); 397 } 398 399 static identity: Symbol = Symbol('hideTitleBar'); 400 401 applyPeer(node: KNode, reset: boolean): void { 402 if (reset) { 403 getUINativeModule().navigation.resetHideTitleBar(node); 404 } else { 405 getUINativeModule().navigation.setHideTitleBar(node, this.value?.isHide, this.value?.animated); 406 } 407 } 408} 409 410class EnableModeChangeAnimationModifier extends ModifierWithKey<boolean | undefined> { 411 constructor(value: boolean | undefined) { 412 super(value); 413 } 414 static identity: Symbol = Symbol('enableModeChangeAnimation'); 415 416 applyPeer(node: KNode, reset: boolean): void { 417 if (reset) { 418 getUINativeModule().navigation.resetEnableModeChangeAnimation(node); 419 } else { 420 getUINativeModule().navigation.setEnableModeChangeAnimation(node, this.value); 421 } 422 } 423} 424 425class HideNavBarModifier extends ModifierWithKey<boolean> { 426 static identity: Symbol = Symbol('hideNavBar'); 427 428 applyPeer(node: KNode, reset: boolean): void { 429 if (reset) { 430 getUINativeModule().navigation.resetHideNavBar(node); 431 } else { 432 getUINativeModule().navigation.setHideNavBar(node, this.value); 433 } 434 } 435} 436 437class IgnoreNavLayoutSafeAreaModifier extends ModifierWithKey<ArkSafeAreaExpandOpts | undefined> { 438 constructor(value: ArkSafeAreaExpandOpts | undefined) { 439 super(value); 440 } 441 static identity: Symbol = Symbol('ignoreLayoutSafeArea'); 442 applyPeer(node: KNode, reset: boolean): void { 443 if (reset) { 444 getUINativeModule().navigation.resetIgnoreLayoutSafeArea(node); 445 } else { 446 getUINativeModule().navigation.setIgnoreLayoutSafeArea(node, this.value.type, this.value.edges); 447 } 448 } 449 checkObjectDiff(): boolean { 450 return !isBaseOrResourceEqual(this.stageValue.type, this.value.type) || 451 !isBaseOrResourceEqual(this.stageValue.edges, this.value.edges); 452 } 453} 454 455class NavigationEnableDragBarModifier extends ModifierWithKey<boolean | undefined> { 456 constructor(value: boolean | undefined) { 457 super(value); 458 } 459 static identity: Symbol = Symbol('enableDragBar'); 460 461 applyPeer(node: KNode, reset: boolean): void { 462 if (reset) { 463 getUINativeModule().navigation.resetEnableDragBar(node); 464 } else { 465 getUINativeModule().navigation.setEnableDragBar(node, this.value); 466 } 467 } 468} 469 470class NavigationRecoverableModifier extends ModifierWithKey<boolean | undefined> { 471 constructor(value: boolean | undefined) { 472 super(value); 473 } 474 static identity: Symbol = Symbol('recoverable'); 475 476 applyPeer(node: KNode, reset: boolean): void { 477 if (reset) { 478 getUINativeModule().navigation.resetRecoverable(node); 479 } else { 480 getUINativeModule().navigation.setRecoverable(node, this.value); 481 } 482 } 483} 484 485// @ts-ignore 486globalThis.Navigation.attributeModifier = function (modifier: ArkComponent): void { 487 attributeModifierFunc.call(this, modifier, (nativePtr: KNode) => { 488 return new ArkNavigationComponent(nativePtr); 489 }, (nativePtr: KNode, classType: ModifierType, modifierJS: ModifierJS) => { 490 return new modifierJS.NavigationModifier(nativePtr, classType); 491 }); 492}; 493