1# ArkUI Subsystem Changelog 2 3 4## cl.arkui.1 Reporting of Unexpected Number of @Extend/@AnimatableExtend Parameters 5 6The @Extend and @AnimatableExtend decorators allow for only one parameter. 7 8**Change Impact** 9 10When there are multiple parameters for the @Extend/@AnimatableExtend decorator, a compilation error is reported. 11 12**Example (incorrect)**: 13 14```ts 15// xxx.ets 16 17@Extend(Text, Button) // Compilation error: @Extend should have one and only one parameter. 18function fancy() { 19 .width(100) 20} 21 22@AnimatableExtend(Text, Polyline) //Compilation error: @AnimatableExtend should have one and only one parameter. 23function fancy2() { 24 .height(100) 25} 26 27@Entry 28@Component 29struct Example { 30 build() { 31 Column() { 32 Text('text') 33 .fancy() 34 .fancy2() 35 } 36 } 37} 38``` 39 40**Key API/Component Changes** 41 42N/A 43 44**Adaptation Guide** 45 46Make sure the @Extend and @AnimatableExtend decorators contain only one parameter. 47 48The code snippet is as follows: 49```ts 50// xxx.ets 51 52@Extend(Text) 53function fancy() { 54 .width(100) 55} 56 57@AnimatableExtend(Text) 58function fancy2() { 59 .height(100) 60} 61 62@Entry 63@Component 64struct Example { 65 build() { 66 Column() { 67 Text('text') 68 .fancy() 69 .fancy2() 70 } 71 } 72} 73``` 74 75## cl.arkui.2 Reporting of @Link/@ObjectLink Member Variables Not Being Configured from Parent Components 76 77The value of an @Link or @ObjectLink decorated member variable in a component must be from the parent component. 78 79**Change Impact** 80 81When the value of an @Link/@ObjectLink decorated member variable in a component is not configured from the parent component, a compilation error is reported. 82 83**Example (incorrect)**: 84 85```ts 86// xxx.ets 87 88@Observed 89class Count { 90 message: string = 'count' 91} 92 93@Entry 94@Component 95struct Parent { 96 @State state1: string = 'state1'; 97 @State state2: Count = new Count(); 98 build() { 99 Column() { 100 Child() // Compilation error: Property 'link' in the custom component 'Child' is missing (mandatory to specify). 101 // Compilation error: Property 'objectLink' in the custom component 'Child' is missing (mandatory to specify). 102 } 103 } 104} 105 106@Component 107struct Child { 108 @Link link: string; 109 @ObjectLink objectLink: Count; 110 build() { 111 Column() { 112 Text(this.link) 113 .fontSize(50) 114 Text(this.objectLink.message) 115 .fontSize(50) 116 } 117 } 118} 119``` 120 121**Key API/Component Changes** 122 123N/A 124 125**Adaptation Guide** 126 127Configure the @Link and @ObjectLink decorated member variables in components to get their values from the parent component. 128 129The code snippet is as follows: 130```ts 131// xxx.ets 132 133@Observed 134class Count { 135 message: string = 'count' 136} 137 138@Entry 139@Component 140struct Parent { 141 @State state1: string = 'state1'; 142 @State state2: Count = new Count(); 143 build() { 144 Column() { 145 Child({link: $state1, objectLink: this.state2}) 146 } 147 } 148} 149 150@Component 151struct Child { 152 @Link link: string; 153 @ObjectLink objectLink: Count; 154 build() { 155 Column() { 156 Text(this.link) 157 .fontSize(50) 158 Text(this.objectLink.message) 159 .fontSize(50) 160 } 161 } 162} 163``` 164## cl.arkui.3 Behavior Change of the onReady Event for \<Canvas> 165 166**Description** 167The **onReady** event is triggered when the component is ready or when the component size changes. After it is triggered, the canvas is cleared. 168 169**Example** 170```ts 171@Entry 172@Component 173struct OnReadyDiff { 174 @State message: string = 'init ' 175 @State isShow: boolean = false 176 @State myHeight: number = 300 177 private settings: RenderingContextSettings = new RenderingContextSettings(true); 178 private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); 179 180 build() { 181 Row() { 182 Column() { 183 Text(this.message) 184 .fontSize(50) 185 .fontWeight(FontWeight.Bold) 186 Button('ChangePosition') 187 .onClick(()=>{ 188 this.isShow = !this.isShow 189 }) 190 if (this.isShow) { 191 Button('new button') 192 .height(200) 193 } 194 Button('ChangeHeight') 195 .onClick(()=>{ 196 this.myHeight = this.myHeight==300?500:300 197 }) 198 199 Canvas(this.context) 200 .width(300) 201 .height(this.myHeight) 202 .backgroundColor('#ffff00') 203 .onReady(() =>{ 204 this.context.fillRect(0, 0, 100, 100) 205 this.message += 'a ' 206 }) 207 Button('draw another') 208 .onClick(()=>{ 209 this.context.fillRect(100, 100, 100, 100) 210 }) 211 } 212 .width('100%') 213 } 214 .height('100%') 215 } 216} 217``` 218 219API version 9: The **onReady** event is triggered when the component is ready, when the component location changes, or when the component size changes. 220 221 222 223API version 10 and later: The **onReady** event is triggered when the component is ready or when the component size changes. It is not triggered when the component location changes. 224 225 226 227**Change Impact** 228 229When the component location changes, the **onReady** event is triggered in API version 9 and earlier versions, but not in API version 10 and later versions. 230 231## cl.arkui.4 Change of How Percentage Is Calculated for Margin 232 233Before the change: The margin is calculated twice when set in percentage. The second calculation is conducted after the result of the first calculation has been subtracted from the percentage reference. After the change: The first margin calculation result is used as the final result, and the second calculation is not conducted. 234 235**Change Impact** 236 237This change affects calculation of margins set in percentage. 238 239**Example (incorrect)**: 240 241```ts 242// xxx.ets 243@Entry 244@Component 245struct TextInputExample { 246 @State text: string = '' 247 controller: TextInputController = new TextInputController() 248 249 build() { 250 Column(){ 251 Row().margin({left:"50%"}).width(100).height(100) 252 }.width("100%").height("100%") 253 } 254} 255``` 256 257**Key API/Component Changes** 258 259N/A 260 261**Adaptation Guide** 262 263After the change, the margin percentage reference is fixed at the parent component's width minus its padding, and does not subtract the result of the first margin calculation. As a result, the margin percentage is slightly greater than that before the change. Account for this change when setting the margin percentage. 264 265## cl.arkui.5 Change of SwipeActionItem in the \<ListItem> Component 266 267Changed **Delete** in the parameters of the **SwipeActionItem** API of the **\<ListItem>** component to **Action**, and deleted the **useDefaultDeleteAnimation** API. 268 269**Change Impact** 270 271When developing an application based on OpenHarmony 4.0.9.3 or a later SDK version, you need to use the new APIs. 272 273**Key API/Component Changes** 274 275| API Before Change | API After Change | 276| ------ | ------------------------------ | 277| deleteAreaDistance | actionAreaDistance | 278| onDelete | onAction | 279| onEnterDeleteArea | onEnterActionArea | 280| onExitDeleteArea | onExitActionArea | 281| useDefaultDeleteAnimation | Deleted| 282 283**Adaptation Guide** 284 285When developing an application based on OpenHarmony 4.0.9.3 or a later SDK version, use the new APIs of **SwipeActionItem**. When developing an application based on OpenHarmony 4.0.9.2 or an earlier SDK version, use the original APIs of **SwipeActionItem**. 286 287The code snippet is as follows: 288 289```ts 290// xxx.ets 291@Entry 292@Component 293struct ListItemExample2 { 294 @State message: string = 'Hello World' 295 @State arr: number[] = [0, 1, 2, 3, 4] 296 @State enterEndDeleteAreaString: string = "not enterEndDeleteArea" 297 @State exitEndDeleteAreaString: string = "not exitEndDeleteArea" 298 299 @Builder itemEnd() { 300 Row() { 301 Button("Delete").margin("4vp") 302 Button("Set").margin("4vp") 303 }.padding("4vp").justifyContent(FlexAlign.SpaceEvenly) 304 } 305 306 build() { 307 Column() { 308 List({ space: 10 }) { 309 ForEach(this.arr, (item) => { 310 ListItem() { 311 Text("item" + item) 312 .width('100%') 313 .height(100) 314 .fontSize(16) 315 .textAlign(TextAlign.Center) 316 .borderRadius(10) 317 .backgroundColor(0xFFFFFF) 318 } 319 .transition({ type: TransitionType.Delete, opacity: 0 }) 320 .swipeAction({ 321 end: { 322 builder: this.itemEnd.bind(this, item), 323 onAction: () => { 324 animateTo({ duration: 1000 }, () => { 325 let index = this.arr.indexOf(item) 326 this.arr.splice(index, 1) 327 }) 328 }, 329 actionAreaDistance: 80, 330 onEnterActionArea: () => { 331 this.enterEndDeleteAreaString = "enterEndDeleteArea" 332 this.exitEndDeleteAreaString = "not exitEndDeleteArea" 333 }, 334 onExitActionArea: () => { 335 this.enterEndDeleteAreaString = "not enterEndDeleteArea" 336 this.exitEndDeleteAreaString = "exitEndDeleteArea" 337 } 338 } 339 }) 340 }, item => item) 341 } 342 Text(this.enterEndDeleteAreaString).fontSize(20) 343 Text(this.exitEndDeleteAreaString).fontSize(20) 344 } 345 .padding(10) 346 .backgroundColor(0xDCDCDC) 347 .width('100%') 348 .height('100%') 349 } 350} 351``` 352