1# ArkUI Changelog 2 3## cl.arkui.1 undefined and null Value Support for State Variables 4 5**Change Impact** 6 7API version 9: State variables do not accept **undefined** or **null** as values. If a state variable is set to **undefined** or **null**, it will remain at its original value. 8 9API version 10: State variables accept **undefined** and **null** as values. You need to check whether a state variable is **undefined**. 10 11**Adaptation Guide** 12 13Since API version 10, you need to take measures to check whether a state variable is **undefined**. 14```ts 15@Entry 16@Component 17struct Page3 { 18 @State messages: string[] = ['Hello World'] 19 20 aboutToAppear() { 21 // If AppStorage does not contain the specified key, undefined is returned. 22 // API version 9: The ArkUI framework rejects undefined as the assigned value, and this.messages is still at its initial value ['Hello World']. 23 // API version 10: The ArkUI framework accepts undefined as the assigned value, and this.messages is undefined. 24 this.messages = AppStorage.Get("aProp") 25 } 26 27 build() { 28 Row() { 29 Column() { 30 // API version 9: The application does not crash, and the value of length is 1. 31 // API version 10: The application crashes, and the following error message is displayed: Cannot read property length of undefined. 32 Text(`the messages length: ${this.messages.length}`) 33 .fontSize(50) 34 .fontWeight(FontWeight.Bold) 35 } 36 .width('100%') 37 } 38 .height('100%') 39 } 40} 41``` 42 43In the preceding scenario, each time **undefined** or **null** is assigned to a state variable, a check for **undefined** state variables is required. 44 45```ts 46Text(`the messages length: ${this.messages?.length}`) 47``` 48 49In API version 10, the ArkUI framework verifies the initialization and value types of state variables, and reports errors found during running. Specifically, there are the following two cases: 501. @Link initialization from the parent component 51 52In the following example, a runtime error is reported, prompting you to initialize @Link. 53```ts 54@Entry 55@Component 56struct Page3 { 57 @State aProp: boolean = true 58 59 build() { 60 Row() { 61 Column() { 62 // crash: SynchedPropertyObjectTwoWayPU[9, 'linkProp']: constructor @Link/@Consume source variable in 63 // parent/ancestor @Component must be defined. Application error! 64 LinkChild() 65 // Incorrect: linkProp is initialized from a regular variable. In this case, the ArkUI framework considers linkProp as not initialized and reports an error. 66 LinkChild({ aProp: false }) 67 // Correct: @Link is initialized from the state variable this.aProp. 68 LinkChild({ aProp: this.aProp }) 69 } 70 .width('100%') 71 } 72 .height('100%') 73 } 74} 75 76@Component 77struct LinkChild { 78 @Link aProp: boolean 79 80 build() { 81 Text(`linkProp: ${this.aProp}`) 82 .fontSize(50) 83 .fontWeight(FontWeight.Bold) 84 } 85} 86``` 87 882. Value type support of state variables 89 90If a state variable is assigned a value in an unsupported type, for example, function, a runtime error is reported. 91```ts 92@Entry 93@Component 94struct Page3 { 95 // API version 10: A runtime error is reported: @Component 'Page3': Illegal variable value error with decorated variable @State/@Provide 'functionProp': failed 96 // validation: 'undefined, null, number, boolean, string, or Object but not function, attempt to assign value type: 'function', 97 @State functionProp: () => void = () => { 98 console.info("123") 99 } 100 101 aboutToAppear() { 102 this.functionProp() 103 } 104 105 build() { 106 Row() { 107 Column() { 108 Text("hello") 109 } 110 .width('100%') 111 } 112 .height('100%') 113 } 114} 115``` 116 117## cl.arkui.2 Adaptation to Component Exceptions After Updating to SDK 4.0.10.x 118After the SDK is updated to 4.0.10.x, the UI components cannot be properly displayed if the device is not using the matching image version. 119 120**Example** 121 122``` 123@Entry 124@Component 125struct Index { // Custom component 126 build() { 127 Text('Hello, world') // Basic component 128 } 129} 130``` 131 132**Change Impact** 133 134If the device where your application runs is not using the matching image version, calling a UI component in the application code will cause 135the error message "this.observeComponentCreation2 is not callable". 136 137**Key API/Component Changes** 138 139N/A 140 141**Adaptation Guide** 142 143Use the matching image on the device. 144 145## cl.arkui.1 Change in Processing for When scrollBar of the \<List> Component Is Set to undefined or an Invalid Value 146 147**Change Impact** 148 149In versions earlier than OpenHarmony_4.0.10.1, the following values evaluate to the default value **BarState.Off**: **scrollBar(undefined)**, **scrollBar('aaa')**, **scrollBar(-1)**.<br> 150In OpenHarmony_4.0.10.2 and later versions, the preceding values evaluate to the default value **BarState.Auto**. 151 152**Key API/Component Changes** 153 154The processing of the **\<List>** component's **scrollBar** attribute, when it is set to **undefined** or an invalid value, is changed from using **BarState.Off** to using **BarState.Auto**. 155 156## cl.arkui.4 Change in Processing for When scrollBar of the \<Grid> Component Is Set to undefined or an Invalid Value 157 158**Change Impact** 159 160In versions earlier than OpenHarmony_4.0.10.1, the following values evaluate to the default value **BarState.Off**: **scrollBar(undefined)**, **scrollBar('aaa')**, **scrollBar(-1)**.<br> 161In OpenHarmony_4.0.10.2 and later versions, the preceding values evaluate to the default value **BarState.Auto**. 162 163**Key API/Component Changes** 164 165The processing of the **\<Grid>** component's **scrollBar** attribute, when it is set to **undefined** or an invalid value, is changed from using **BarState.Off** to using **BarState.Auto**. 166 167 168## cl.arkui.5 Method Name Changes in NavPathStack 169 170**Key API/Component Changes** 171 172[NavPathStack](../../../application-dev/reference/arkui-ts/ts-basic-components-navigation.md#navpathstack10) 173| Before Change | After Change | 174| ---- | ---- | 175| push | pushPath | 176| pushName | pushNameByPath | 177| popTo| PopToName | 178 179**Change Impact** 180 181After the SDK is updated to 4.0.10.x, if any of the old method names is used in the code, a compilation error will be reported. 182Property 'push' does not exist on type 'NavPathStack'. 183Property 'pushName' does not exist on type 'NavPathStack'. 184Property 'pop' does not exist on type 'NavPathStack'. 185 186**Adaptation Guide** 187 188Update the code to use the new method names. 189 190```ts 191navPathStack = new NavPathStack(); 192this.navPathStack.push(...) 193this.navPathStack.pushPath(...) 194 195this.navPathStack.pushName('navidesnation_add',this.value) 196this.navPathStack.pushPathByName('navidesnation_add',this.value) 197 198this.navPathStack.pop('navidesnation_add') 199this.navPathStack.popToName('navidesnation_add') 200``` 201 202## cl.arkui.6 setLineDash Implementation Change 203 204 205Changed the unit of the **number** parameter in the **setLineDash** API from px to vp. 206 207**Example** 208```ts 209@Entry 210@Component 211struct SetLineDash { 212 private settings: RenderingContextSettings = new RenderingContextSettings(true) 213 private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) 214 215 build() { 216 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 217 Canvas(this.context) 218 .width('100%') 219 .height('100%') 220 .backgroundColor('#ffff00') 221 .onReady(() =>{ 222 let ctx = this.context 223 ctx.lineWidth = 5 224 ctx.arc(100, 75, 50, 0, 6.28) 225 ctx.setLineDash([10,20]) 226 ctx.stroke(); 227 }) 228 Image('image/SetLineDash.png') 229 .objectFit(ImageFit.Contain) 230 } 231 .width('100%') 232 .height('100%') 233 } 234} 235``` 236API version 9: The unit of the **number** parameter in the **setLineDash** API is px. 237 238 239 240API version 10 and later: The unit of the **number** parameter in the **setLineDash** API is vp. 241 242 243 244**Change Impact** 245 246The drawing effect of the **setLineDash** API in API version 9 or earlier is different from that in API version 10 or later. 247 248## cl.arkui.7 Change in the Custom Navigation Title Position 249 2501. **NavigationTitleMode** is set to **Full**, **Free**, or **Mini** without the back button. 251 252 API version 9: The left margin remains at 24 vp. 253 254 API version 10: The left margin is changed from 24 vp to 0. The top margin is changed from center to 0. 255 2562. **NavigationTitleMode** is set to **Mini** and the back button is displayed. 257 258 API version 9: The spacing between the custom title and the back button is 16 vp. 259 260 API version 10: The spacing between the custom title bar and the back button is changed from 16 vp to 12 vp. 261 2623. A custom menu is configured. 263 264 API version 9: The right margin is 24 vp. 265 266 API version 10: The right margin is changed from 24 vp to 0. 267 268**Reason for Change** 269 270Since API version 9, offsets are added the custom title and menu of the **\<Navigation>** component, which affects the use of custom components. Since OpenHarmony 4.0.10.6, the offsets are removed from applications in API version 10. 271 272**Change Impact** 273 274In API version 10, the custom navigation title is displayed on the left of or above the position where it would appear in previous API versions. 275 276**Adaptation Guide** 277 2781. For **NavigationTitleMode.Full**, **NavigationTitleMode.Free**, and **NavigationTitleMode.Mini**, you can add a left margin by using **$r('sys.float.ohos_id_max_padding_start')**. 279To center the title on the top, use **.height('100%').alignItems(VerticalAlign.Center)**. 280 2812. For **NavigationTitleMode.Mini** with the back button displayed, you can add a left margin by using **.margin({left: 4})**. To center the title on the top, use **.height('100%').alignItems(VerticalAlign.Center)**. 282 2833. When a custom menu is configured, you can add a right margin by using **.margin({right: $r('sys.float.ohos_id_max_padding_end')})**. 284 285 286**Example** 287```ts 288@Entry 289@Component 290struct Index { 291 @State titleMode: NavigationTitleMode = NavigationTitleMode.Free 292 @State backButton: boolean = false; 293 @Builder CustomMenu() { 294 Column() { 295 Image($r('app.media.icon')).width(24).height(24) 296 } 297 } 298 299 @Builder CustomTitle() { 300 Column() { 301 Text('Custom title').fontSize(20) 302 } 303 } 304 305 build() { 306 Column() { 307 Navigation() { 308 Column() { 309 Text(`Change current title mode: ${this.titleMode}`) 310 .onClick(()=>{ 311 if (this.titleMode == NavigationTitleMode.Free) { 312 this.titleMode = NavigationTitleMode.Full; 313 } else if (this.titleMode == NavigationTitleMode.Full) { 314 this.titleMode = NavigationTitleMode.Mini; 315 } else { 316 this.titleMode = NavigationTitleMode.Free; 317 } 318 }) 319 320 Text(`Change back button: ${this.backButton}`).onClick(()=>{ 321 this.backButton = !this.backButton; 322 }).margin({top: 10}) 323 }.margin({top: 40}) 324 }.title(this.CustomTitle) 325 .titleMode(this.titleMode) 326 .menus(this.CustomMenu) 327 .hideBackButton(this.backButton) 328 } 329 } 330} 331``` 332API version 9: Custom title and menu in **NavigationTitleMode.Full** settings 333 334 335 336API version 10: Custom title and menu in **NavigationTitleMode.Full** settings 337 338 339 340API version 9: Custom title with the back button in **NavigationTitleMode.Mini** settings 341 342 343 344API version 10: Custom title with the back button in **NavigationTitleMode.Mini** settings 345 346 347 348API version 9: Custom title without the back button in **NavigationTitleMode.Mini** settings 349 350 351 352API version 10: Custom title without the back button in **NavigationTitleMode.Mini** settings 353 354 355 356## cl.arkui.8 Title Bar Change of the \<NavDestination> Component 357 358For custom titles: 359 3601. With the back button 361 362 API version 9: The spacing between the back button and the title bar is 16 vp, and the title bar is centered. 363 364 API version 10: The spacing between the back button and the title bar is changed from 16 vp to 12 vp, and the top offset of the title bar is changed to 0. 365 3662. Without the back button 367 368 API version 9: The title bar is centered, with a left margin of 24 vp. 369 370 API version 10: The left margin of the title bar is changed from 24 vp to 0, and its top offset is changed to 0. 371 372**Reason for Change** 373 374Since API version 9, offsets are added to the custom title of the **\<Navigation>** component, which affects the use of custom components. Since OpenHarmony 4.0.10.6, the offsets are removed from applications in API version 10. 375 376**Change Impact** 377The custom title bar of the **\<NavDestination>** component is displayed in the upper left corner of the position where it would appear in previous API versions. 378 379**Adaptation Guide** 380 381To retain the display effect in previous versions, you can use the following solution: 382 3831. Where the back button is not displayed: Add a left offset by using **margin({left: $r('sys.float.ohos_id_max_padding_start')})**. 384To center the title bar on the top, use **.height ('100%').alignItems (VerticalAlign.Center)**. 385 3862. Where the back button is displayed: Add a left offset by using **margin ({left: 4})**. To center the title bar on the top, use **.height ('100%').alignItems (VerticalAlign.Center)**. 387 388**Example** 389```ts 390@Entry 391@Component 392struct Index { 393 @Builder NavigationTile() { 394 Column() { 395 Text('title').fontColor('#182431').fontSize(30).lineHeight(41) 396 Text('subTitle').fontColor('#182431').fontSize(14).lineHeight(19).margin(top:2, bottom: 20) 397 } 398 } 399 400 build() { 401 Column() { 402 Navigation() { 403 Text('Navigation') 404 }.title(this.NavigationTitle) 405 .titleMode(NavigationTitleMode.Free) 406 .menus([ 407 {icon: 'common/image/icon.png', value: 'menu1'} 408 ]) 409 } 410 } 411} 412``` 413 414API version 9: Custom title bar with the back button 415 416 417 418API version 10: Custom title bar with the back button 419 420 421 422API version 9: Custom title bar without the back button 423 424 425 426API version 10: Custom title bar without the back button 427 428 429 430## cl.arkui.9 OnStateChange Callback Change of the \<NavRouter> Component 431 432Fixed the number of **OnStateChange** calls: 433 434The number of the **OnStateChange** calls for displaying the **\<NavDestination>** component is changed from twice to once, which does not affect the call sequence. 435 436**Change Impact** 437 438Applications that use **OnStateChange** for call timing are affected. 439 440 Call sequence before the change: **OnStateChange(true)** triggered by display of **\<NavRouter>** -> **OnStateChange(false)** triggered by exiting of **\<NavRouter>** -> **OnStateChange(true)** triggered by display of **\<NavRouter>** 441 442 Call sequence after the change: **OnStateChange(true)** triggered by display of **\<NavRouter>** -> **OnStateChange(false)** triggered by exiting of **\<NavRouter>** 443 444## cl.arkui.10 Value Change of the PanelHeight Enum WRAP_CONTENT from 0 to 'wrapContent' 445 446**Change Impact** 447 448Before the change, both **customHeight(0)** and **customHeight(PanelHeight.WRAP_CONTENT)** configure the component to adapt to the content height.<br> 449After the change, **customHeight(0)** sets the content height to **0**, and **customHeight(PanelHeight.WRAP_CONTENT)** configures the component to adapt to the content height. 450 451**Key API/Component Changes** 452 453The value of **WRAP_CONTENT** of the **PanelHeight** enum is changed from **0** to **'wrapContent'**. This API behavior change does not affect your use of the API. 454 455## cl.arkui.11 Change of the Default Value for aspectRatio Set to an Invalid Value or undefined 456 457**Change Impact** 458 459Before the change, if **aspectRatio** is set to a negative value or **undefined**, the default value **1.0** is used. 460 461After the change, if **aspectRatio** is set to a negative value or **undefined**, the default value **null** is used. For example, if a **\<Row>** component has only its width set and does not have any child component, then when **aspectRatio** is not set or is set to a negative value, the height of the **\<Row>** component is 0. 462 463## cl.arkui.12 Change of Effect in Setting defaultFocus to true 464 465**Change Impact** 466In versions earlier than 4.0.9.1, setting **defaultFocus** to **true** does not take effect. 467 468In 4.0.9.1 and later versions, setting **defaultFocus** to **true** takes effect. 469 470## cl.arkui.13 Change of Focus Navigation for tabIndex 471 472**Change Impact** 473In versions earlier than 4.0.10.2, the focus navigation for **tabIndex** is not cyclic. 474 475In 4.0.10.2 and later versions, the focus navigation for **tabIndex** is cyclic. 476 477## cl.arkui.14 Change of Constraint Calculation for the \<TextInput> Component 478 479**Change Impact** 480 481In versions earlier than 4.0.10.2, when **margin** is set for the **\<TextInput>** component, the value of **margin** is subtracted from the component's constraint. 482 483In versions earlier than 4.0.10.2, the value of **margin** is not subtracted from the **\<TextInput>** component's constraint. 484 485 486## cl.arkui.15 Change in Handling Rules on Negative Values of fontSize for Buttons 487 488**Change Impact** 489 490Before change, a negative value of **fontSize** evaluates to **0**. That is, the text is not displayed.<br> 491After change, a negative value of **fontSize** evaluates to the default value **16fp**.<br> 492Note: This change does not affect the effect of **fontSize=0**. 493 494## cl.arkui.16 Change in the Search Text Box for When the Attributes of the \<Search> Component Are Dynamically Changed 495 496**Change Impact** 497 498Before change, when **placeholder**, but not **value**, is set for the **\<Search>** component, dynamically changing the component attributes will clear the search text box.<br> 499After change, when **placeholder**, but not **value**, is set for the **\<Search>** component, dynamically changing the component attributes will not clear the search text box. 500Note: After change, the behavior of the **\<Search>** component is what is expected of the component in normal cases. 501 502## cl.arkui.17 Change in the Width Specification of the \<Menu> Component 503 504Changed the width specification of the [\<Menu>](../../../application-dev/reference/arkui-ts/ts-basic-components-menu.md) component as follows: If the width is not set, the component takes up two columns. If the width is set, the component adapts its content to the set width. The **\<Menu>** component has a default minimum width of 64 vp. 505 506**Change Impact** 507 5081. By default, the menu takes up two columns. If the content of the [\<MenuItem>](../../../application-dev/reference/arkui-ts/ts-basic-components-menuitem.md) is wider than 2 columns, the menu width is automatically extended. 5092. The default minimum width of the menu is 64 vp. You can change the minimum width through the [constraintSize](../../../application-dev/reference/arkui-ts/ts-universal-attributes-size.md) attribute. 510 511**Key API/Component Changes** 512 513- [Menu](../../../application-dev/reference/arkui-ts/ts-basic-components-menu.md) 514 515**Adaptation Guide** 516 517You can set the minimum width to a value less than 64 vp or remove the limit altogether, by setting **constraintSize**. 518 519**Example** 520```ts 521@Entry 522@Component 523struct Index { 524 @Builder 525 MyMenu(){ 526 Menu() { 527 MenuItem({ startIcon: $r("app.media.icon"), content: "Menu option" }) 528 } 529 .width(30) 530 .constraintSize({minWidth: 0}) //Overwrite the default minimum width of 64 vp. 531 } 532 533 build() { 534 Row() { 535 Column() { 536 Text('click to show menu') 537 } 538 .bindMenu(this.MyMenu) 539 .width('100%') 540 } 541 .height('100%') 542 } 543} 544``` 545 546## cl.arkui.18 Change in the Velocity Direction Specification of springCurve 547 548**Change Impact** 549 550In API version 9, when the [interpolate](../../../application-dev/reference/apis/js-apis-curve.md#interpolate9) method of [springCurve](../../../application-dev/reference/apis/js-apis-curve.md#curvesspringcurve9) is used for calculation, an initial velocity greater than 0 means to move in the reverse direction of the end point, and an initial velocity less than 0 means move in the direction of the end point.<br> 551Since API version 10, when the **interpolate** method of **springCurve** is used for calculation, an initial velocity greater than 0 means to move in the direction of the end point, and an initial velocity less than 0 means move in the reverse direction of the end point. As a result, when the initial velocity is not 0, the result obtained using the **interpolate** method of **springCurve** in API version 10 is different from that in API version 9. 552 553## cl.arkui.5 Change in the Actual Curve Time Estimation Threshold Specification of springCurve 554 555**Change Impact** 556 557In API version 9, the maximum duration estimated by the [interpolate](../../../application-dev/reference/apis/js-apis-curve.md#interpolate9) method of [springCurve](../../../application-dev/reference/apis/js-apis-curve.md#curvesspringcurve9) for the actual spring curve is 1 second. When the physics-based curve duration exceeds 1 second, the estimated duration is still 1 second. As a result, the animation duration of the spring curve that exceeds 1 second is incorrectly normalized, and the interpolation result changes abruptly when t=1.<br> 558Since API version 10, the maximum duration estimated by the **interpolate** method of **springCurve** is 1000 seconds, so as to cover most spring curves. This change will result in differences from the calculation results by the **interpolate** method of **springCurve** in API versions earlier than 10. 559 560## cl.arkui.19 uiAppearance API Behavior Change 561 562Changed the return mode and return value of the **setDarkMode** and **getDarkMode** APIs. 563 564**Change Impact** 565 566The application developed based on earlier versions needs to adapt to new return mode and return value. Otherwise, the original service logic will be affected. 567 568**Key API/Component Changes** 569 570 571- In the error thrown when the **setDarkMode** API is called in callback mode, what's contained changes from error code ID only to error code ID and message. 572- In the error thrown when the **setDarkMode** API is called in promise mode, what's contained changes from error code ID only to error code ID and message. 573- In the value returned in normal cases when the **setDarkMode** API is called in callback mode, the first parameter changes from **0** to **null**. 574- In the earlier version, the **getDarkMode** API directly returns **2** when an exception occurs. In this version, the API throws an error. You need to determine the error type based on the error code ID and message. 575 576**NOTE**<br>Exceptions refer to unexpected behavior such as incorrect parameters, unconfigured permissions, and internal execution errors. Normal cases refer to expected behavior that do not generate errors. 577 578**Adaptation Guide** 579 580For details, see [@ohos.uiAppearance (UI Appearance)](../../../application-dev/reference/apis/js-apis-uiappearance.md). 581