1# Popup Control 2 3You can bind a popup to a component, specifying its content, interaction logic, and visibility. 4 5> **NOTE** 6> 7> - This attribute is supported since API version 7. Updates will be marked with a superscript to indicate their earliest API version. 8> 9> - The visibility of the popup is returned through the **onStateChange** event callback. There is no strong mapping between the visibility and the creation or destruction of the component. 10 11## bindPopup 12 13bindPopup(show: boolean, popup: PopupOptions | CustomPopupOptions) 14 15Binds a popup to the component. 16 17**Atomic service API**: This API can be used in atomic services since API version 11. 18 19**System capability**: SystemCapability.ArkUI.ArkUI.Full 20 21**Parameters** 22 23| Name| Type | Mandatory| Description | 24| ------ | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | 25| show | boolean | Yes | Whether to show the popup. The default value is **false**, indicating that the popup is hidden. The popup can be displayed only after the entire page is fully constructed. Therefore, to avoid incorrect display positions and shapes, do not set this parameter to **true** while the page is still being constructed. This parameter supports two-way binding through [!! Syntax](../../../quick-start/arkts-new-binding.md).| 26| popup | [PopupOptions](#popupoptions) \| [CustomPopupOptions](#custompopupoptions8)<sup>8+</sup> | Yes | Parameters of the popup. | 27 28## PopupOptions 29 30| Name | Type | Mandatory| Description | 31| ------------------------------------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | 32| message | string | Yes | Content of the popup message.<br>**Atomic service API**: This API can be used in atomic services since API version 11. | 33| placementOnTop<sup>(deprecated)</sup> | boolean | No | Whether to display the popup above the component. The default value is **false**.<br>**NOTE**<br>This API is deprecated since API version 10. You are advised to use **placement** instead.| 34| primaryButton | {<br>value: string,<br>action: () => void<br>} | No | Primary button.<br>**value**: text of the primary button in the popup.<br>**action**: callback for clicking the primary button.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 35| secondaryButton | {<br>value: string,<br>action: () => void<br>} | No | Secondary button.<br>**value**: text of the secondary button in the popup.<br>**action**: callback for clicking the secondary button.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 36| onStateChange | (event: { isVisible: boolean }) => void | No | Callback for the popup status change event. The parameter **isVisible** indicates whether the popup is visible.<br>**Atomic service API**: This API can be used in atomic services since API version 11. | 37| arrowOffset<sup>9+</sup> | [Length](ts-types.md#length) | No | Offset of the popup arrow relative to the popup. When the arrow is at the top or bottom of the popup: The value **0** indicates that the arrow is located on the leftmost, and any other value indicates the distance from the arrow to the leftmost; the arrow is centered by default. When the arrow is on the left or right side of the popup: The value indicates the distance from the arrow to the top; the arrow is centered by default. When the popup is displayed on either edge of the screen, it will automatically deviate leftward or rightward to stay within the safe area. When the value is 0, the arrow always points to the bound component.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 38| showInSubWindow<sup>9+</sup> | boolean | No | Whether to show the popup in the subwindow. The default value is **false**.<br>**Atomic service API**: This API can be used in atomic services since API version 11. | 39| mask<sup>10+</sup> | boolean \| { color : [ResourceColor](ts-types.md#resourcecolor) }| No | Whether to apply a mask to the popup. The value **true** means to apply a transparent mask to the popup, **false** means not to apply a mask to the popup, and a color value means to apply a mask in the corresponding color to the popup.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 40| messageOptions<sup>10+</sup> | [PopupMessageOptions](#popupmessageoptions10) | No | Parameters of the popup message.<br>**Atomic service API**: This API can be used in atomic services since API version 11. | 41| targetSpace<sup>10+</sup> | [Length](ts-types.md#length) | No | Space between the popup and the target.<br>**Atomic service API**: This API can be used in atomic services since API version 11. | 42| placement<sup>10+</sup> | [Placement](ts-appendix-enums.md#placement8) | No | Position of the popup relative to the target. The default value is **Placement.Bottom**.<br>If both **placementOnTop** and **placement** are set, the latter prevails.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 43| offset<sup>10+</sup> | [Position](ts-types.md#position) | No | Offset of the popup relative to the display position specified by **placement**.<br>**NOTE**<br>This parameter cannot be set in percentage.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 44| enableArrow<sup>10+</sup> | boolean | No | Whether to display the arrow.<br>Default value: **true**<br>**NOTE**<br>If the available space on the screen is insufficient, the popup will cover part of the component and the arrow will not be displayed.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 45| popupColor<sup>11+</sup> | [Color](ts-appendix-enums.md#color) \| string \| number \| [Resource](ts-types.md#resource) | No | Color of the popup. To remove the background blur, set **backgroundBlurStyle** to **BlurStyle.NONE**.<br>Default value: [TRANSPARENT](ts-appendix-enums.md#color) plus[COMPONENT_ULTRA_THICK](ts-universal-attributes-background.md#blurstyle9)<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 46| autoCancel<sup>11+</sup> | boolean | No | Whether to automatically dismiss the popup when an operation is performed on the page.<br>Default value: **true**<br>**Atomic service API**: This API can be used in atomic services since API version 12. | 47| width<sup>11+</sup> | [Dimension](ts-types.md#dimension10) | No | Width of the popup.<br>**NOTE**<br>When **showInSubWindow** is set to **true**, the maximum height of the popup is the height of the device screen. When **showInSubWindow** is set to **false**, the maximum height is the height of the application window. Allowable height = Maximum height – Status bar height (0 if there is no status bar) – Dock height (0 if there is no dock) – 40 vp – 40 vp.<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 48| arrowPointPosition<sup>11+</sup> | [ArrowPointPosition](ts-appendix-enums.md#arrowpointposition11) | No | Position of the popup arrow relative to its parent component. Available positions are **Start**, **Center**, and **End**, in both vertical and horizontal directions. All these positions are within the parent component area.<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 49| arrowWidth<sup>11+</sup> | [Dimension](ts-types.md#dimension10) | No | Arrow thickness. If the arrow thickness exceeds the length of the edge minus twice the size of the popup rounded corner, the arrow is not drawn.<br>Default value: **16**<br>Unit: vp<br>**NOTE**<br>This parameter cannot be set in percentage.<br>**Atomic service API**: This API can be used in atomic services since API version 12. | 50| arrowHeight<sup>11+</sup> | [Dimension](ts-types.md#dimension10) | No | Arrow height.<br>Default value: **8**<br>Unit: vp<br>**NOTE**<br>This parameter cannot be set in percentage.<br>**Atomic service API**: This API can be used in atomic services since API version 12. | 51| radius<sup>11+</sup> | [Dimension](ts-types.md#dimension10) | No | Rounded corner radius of the popup.<br>Default value: **20**<br>Unit: vp<br>**Atomic service API**: This API can be used in atomic services since API version 12. | 52| shadow<sup>11+</sup> | [ShadowOptions](ts-universal-attributes-image-effect.md#shadowoptions) \| [ShadowStyle](ts-universal-attributes-image-effect.md#shadowstyle10) | No | Popup shadow.<br>Default value: **ShadowStyle.OUTER_DEFAULT_MD**<br>**Atomic service API**: This API can be used in atomic services since API version 12. | 53| backgroundBlurStyle<sup>11+</sup> | [BlurStyle](ts-universal-attributes-background.md#blurstyle9) | No| Background blur style of the popup.<br>Default value: **BlurStyle.COMPONENT_ULTRA_THICK**<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 54| transition<sup>12+</sup> | [TransitionEffect](ts-transition-animation-component.md#transitioneffect10) | No| Transition effect for the entrance and exit of the popup.<br>**NOTE**<br>1. If this parameter is not set, the default effect is used.<br>2. Touching the Back button during the entrance animation pauses the entrance animation and starts the exit animation. The final effect is one obtained after the curves of the entrance and exit animations are combined.<br>3. Touching the Back button during the exit animation does not affect the animation playback. The Back button does not respond.<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 55| onWillDismiss<sup>12+</sup> | boolean\|(dismissPopupAction: [DismissPopupAction](#dismisspopupaction12)) => void | No | Whether to perform dismissal event interception and interception callback. The default value is **true**.<br>1. If this parameter is set to **false**, the system does not respond to the dismissal event initiated by touching the Back button, swiping left or right on the screen, or pressing the Esc key; and the system dismisses the popup only when **show** is set to **false**. If this parameter is set to **true**, the system responds to the dismissal event as expected.<br>2. If this parameter is set to a function, the dismissal event is intercepted and the callback function is executed.<br>**NOTE**<br>No more **onWillDismiss** callback is allowed in an **onWillDismiss** callback.<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 56| followTransformOfTarget<sup>13+</sup> | boolean | No | Whether the popup adjusts its position to follow transformations (like rotation or scaling) applied to its host component or the host component's parent container.<br>Default value: **false**<br>**Atomic service API**: This API can be used in atomic services since API version 13.| 57 58## PopupMessageOptions<sup>10+</sup> 59 60**Atomic service API**: This API can be used in atomic services since API version 11. 61 62| Name | Type | Mandatory| Description | 63| --------- | ------------------------------------------ | ---- | ------------------------------------------------------------ | 64| textColor | [ResourceColor](ts-types.md#resourcecolor) | No | Text color of the popup message. | 65| font | [Font](ts-types.md#font) | No | Font settings of the popup message.<br>**NOTE**<br>Setting **family** is not supported.| 66 67## DismissPopupAction<sup>12+</sup> 68 69**Atomic service API**: This API can be used in atomic services since API version 12. 70 71| Name | Type | Mandatory| Description | 72| ------- | ----------------------------------------- | ---- | --------------------------------------------------------------- | 73| dismiss | function | Yes | Callback for dismissing the popup. This API is called only when the popup needs to be exited.| 74| reason | [DismissReason](#dismissreason12)| Yes | Reason why the popup cannot be dismissed. | 75 76## DismissReason<sup>12+</sup> 77 78 79| Name | Description | 80| ------------- | ------------------ | 81| PRESS_BACK | Touching the Back button. | 82| TOUCH_OUTSIDE | Touching anywhere outside of the popup.| 83 84## CustomPopupOptions<sup>8+</sup> 85 86| Name | Type | Mandatory | Description | 87| ---------------------------- | ---------------------------------------- | ---- | ---------------------------------------- | 88| builder | [CustomBuilder](ts-types.md#custombuilder8) | Yes | Popup builder.<br>**NOTE**<br>The **popup** attribute is a universal attribute. A custom popup does not support display of another popup. The **position** attribute cannot be used for the first-layer container in the builder. If the **position** attribute is used, the popup will not be displayed. If a custom component is used in the builder, the **aboutToAppear** and **aboutToDisappear** lifecycle callbacks of the custom component are irrelevant to the visibility of the popup. As such, the lifecycle of the custom component cannot be used to determine whether the popup is displayed or not.<br>**Atomic service API**: This API can be used in atomic services since API version 11. | 89| placement | [Placement](ts-appendix-enums.md#placement8) | No | Preferred position of the popup. If the set position is insufficient for holding the popup, it will be automatically adjusted.<br>Default value: **Placement.Bottom**<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 90| popupColor | number \| [Color](ts-types.md#color) \| string \| [Resource](ts-types.md#resource) | No | Color of the popup. To remove the background blur, set **backgroundBlurStyle** to **BlurStyle.NONE**.<br>The default value varies by API version.<br>API version 10: **'#4d4d4d'**<br>API version 11 and later: [TRANSPARENT](ts-appendix-enums.md#color) plus [COMPONENT_ULTRA_THICK](ts-universal-attributes-background.md#blurstyle9)<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 91| enableArrow | boolean | No | Whether to display an arrow.<br>Since API version 9, if the position set for the popup is not large enough, the arrow will not be displayed. For example, if **placement** is set to **Left**, but the popup height (80 vp) is less than the sum of the arrow width (32 vp) and diameter of popup rounded corner (48 vp), the arrow will not be displayed.<br>Default value: **true**<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 92| autoCancel | boolean | No | Whether to automatically dismiss the popup when an operation is performed on the page.<br>Default value: **true**<br>**NOTE**<br>To enable the popup to disappear upon a click on it, place a layout component in the builder, place the **\<Popup>** component in the layout component, and modify the value of the **bindPopup** variable (show: boolean) in the **onClick** event of the layout component.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 93| onStateChange | (event: { isVisible: boolean }) => void | No | Callback for the popup status change event. The parameter **isVisible** indicates whether the popup is visible.<br>**Atomic service API**: This API can be used in atomic services since API version 11. | 94| arrowOffset<sup>9+</sup> | [Length](ts-types.md#length) | No | Offset of the popup arrow relative to the popup. When the arrow is at the top or bottom of the popup: The value **0** indicates that the arrow is located on the leftmost, and any other value indicates the distance from the arrow to the leftmost; the arrow is centered by default. When the arrow is on the left or right side of the popup: The value indicates the distance from the arrow to the top; the arrow is centered by default. When the popup is displayed on either edge of the screen, it will automatically deviate leftward or rightward to stay within the safe area. When the value is 0, the arrow always points to the bound component.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 95| showInSubWindow<sup>9+</sup> | boolean | No | Whether to show the popup in the subwindow. The default value is **false**.<br>**Atomic service API**: This API can be used in atomic services since API version 11. | 96| maskColor<sup>(deprecated)</sup> | [Resource](ts-types.md#resource) \| string \| number \| [Color](ts-types.md#color) | No | Color of the popup mask.<br>**NOTE**<br>This parameter is deprecated since API version 10. You are advised to use **mask** instead.| 97| mask<sup>10+</sup> | boolean \| { color : [ResourceColor](ts-types.md#resourcecolor) }| No | Whether to apply a mask to the popup. The value **true** means to apply a transparent mask to the popup, **false** means not to apply a mask to the popup, and a color value means to apply a mask in the corresponding color to the popup.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 98| targetSpace<sup>10+</sup> | [Length](ts-types.md#length) | No | Space between the popup and the target.<br>**Atomic service API**: This API can be used in atomic services since API version 11. | 99| offset<sup>10+</sup> | [Position](ts-types.md#position) | No | Offset of the popup relative to the display position specified by **placement**.<br>**NOTE**<br>This parameter cannot be set in percentage.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 100| width<sup>11+</sup> | [Dimension](ts-types.md#dimension10) | No| Width of the popup.<br>**NOTE**<br>When **showInSubWindow** is set to **true**, the maximum height of the popup is the height of the device screen. When **showInSubWindow** is set to **false**, the maximum height is the height of the application window. Allowable height = Maximum height – Status bar height (0 if there is no status bar) – Dock height (0 if there is no dock) – 40 vp – 40 vp.<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 101| arrowPointPosition<sup>11+</sup> | [ArrowPointPosition](ts-appendix-enums.md#arrowpointposition11) | No| Position of the popup arrow relative to its parent component. Available positions are **Start**, **Center**, and **End**, in both vertical and horizontal directions. All these positions are within the parent component area.<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 102| arrowWidth<sup>11+</sup> | [Dimension](ts-types.md#dimension10) | No | Arrow thickness. If the arrow thickness exceeds the length of the edge minus twice the size of the popup rounded corner, the arrow is not drawn.<br>Default value: **16**<br>Unit: vp<br>**NOTE**<br>This parameter cannot be set in percentage.<br>**Atomic service API**: This API can be used in atomic services since API version 12. | 103| arrowHeight<sup>11+</sup> | [Dimension](ts-types.md#dimension10) | No | Arrow height.<br>Default value: **8**<br>Unit: vp<br>**NOTE**<br>This parameter cannot be set in percentage.<br>**Atomic service API**: This API can be used in atomic services since API version 12. | 104| radius<sup>11+</sup> | [Dimension](ts-types.md#dimension10) | No | Rounded corner radius of the popup.<br>Default value: **20**<br>Unit: vp<br>**Atomic service API**: This API can be used in atomic services since API version 12. | 105| shadow<sup>11+</sup> | [ShadowOptions](ts-universal-attributes-image-effect.md#shadowoptions) \| [ShadowStyle](ts-universal-attributes-image-effect.md#shadowstyle10) | No | Popup shadow.<br>Default value: **ShadowStyle.OUTER_DEFAULT_MD**<br>**Atomic service API**: This API can be used in atomic services since API version 12. | 106| backgroundBlurStyle<sup>11+</sup> | [BlurStyle](ts-universal-attributes-background.md#blurstyle9) | No| Background blur style of the popup.<br>Default value: **BlurStyle.COMPONENT_ULTRA_THICK**<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 107| focusable<sup>11+</sup> | boolean | No| Whether the popup obtains focus when displayed.<br>Default value: **false**<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 108| transition<sup>12+</sup> | [TransitionEffect](ts-transition-animation-component.md#transitioneffect10) | No| Transition effect for the entrance and exit of the popup.<br>**NOTE**<br>1. If this parameter is not set, the default effect is used.<br>2. Touching the Back button during the entrance animation pauses the entrance animation and starts the exit animation. The final effect is one obtained after the curves of the entrance and exit animations are combined.<br>3. Touching the Back button during the exit animation does not affect the animation playback. The Back button does not respond.<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 109| onWillDismiss<sup>12+</sup> | boolean\|(dismissPopupAction: [DismissPopupAction](#dismisspopupaction12)) => void | No | Whether to perform dismissal event interception and interception callback. The default value is **true**.<br>1. If this parameter is set to **false**, the system does not respond to the dismissal event initiated by touching the Back button, swiping left or right on the screen, or pressing the Esc key; and the system dismisses the popup only when **show** is set to **false**. If this parameter is set to **true**, the system responds to the dismissal event as expected.<br>2. If this parameter is set to a function, the dismissal event is intercepted and the callback function is executed.<br>**NOTE**<br>No more **onWillDismiss** callback is allowed in an **onWillDismiss** callback.<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 110| followTransformOfTarget<sup>13+</sup> | boolean | No | Whether the popup adjusts its position to follow transformations (like rotation or scaling) applied to its host component or the host component's parent container.<br>Default value: **false**<br>**Atomic service API**: This API can be used in atomic services since API version 13.| 111 112## Example 113 114### Example 1: Displaying Different Types of Popups 115 116This example showcases how to use the **bindPopup** API to configure and display popups of PopupOptions and CustomPopupOptions types. 117 118```ts 119// xxx.ets 120@Entry 121@Component 122struct PopupExample { 123 @State handlePopup: boolean = false 124 @State customPopup: boolean = false 125 126 // Popup builder 127 @Builder popupBuilder() { 128 Row({ space: 2 }) { 129 Image($r("app.media.icon")).width(24).height(24).margin({ left: -5 }) 130 Text('Custom Popup').fontSize(10) 131 }.width(100).height(50).padding(5) 132 } 133 134 build() { 135 Flex({ direction: FlexDirection.Column }) { 136 // PopupOptions for setting the popup 137 Button('PopupOptions') 138 .onClick(() => { 139 this.handlePopup = !this.handlePopup 140 }) 141 .bindPopup(this.handlePopup, { 142 message: 'This is a popup with PopupOptions', 143 placementOnTop: true, 144 showInSubWindow:false, 145 primaryButton: { 146 value: 'confirm', 147 action: () => { 148 this.handlePopup = !this.handlePopup 149 console.info('confirm Button click') 150 } 151 }, 152 // Secondary button 153 secondaryButton: { 154 value: 'cancel', 155 action: () => { 156 this.handlePopup = !this.handlePopup 157 console.info('cancel Button click') 158 } 159 }, 160 onStateChange: (e) => { 161 console.info(JSON.stringify(e.isVisible)) 162 if (!e.isVisible) { 163 this.handlePopup = false 164 } 165 } 166 }) 167 .position({ x: 100, y: 150 }) 168 169 170 // CustomPopupOptions for setting the popup 171 Button('CustomPopupOptions') 172 .onClick(() => { 173 this.customPopup = !this.customPopup 174 }) 175 .bindPopup(this.customPopup, { 176 builder: this.popupBuilder, 177 placement: Placement.Top, 178 mask: {color:'#33000000'}, 179 popupColor: Color.Yellow, 180 enableArrow: true, 181 showInSubWindow: false, 182 onStateChange: (e) => { 183 if (!e.isVisible) { 184 this.customPopup = false 185 } 186 } 187 }) 188 .position({ x: 80, y: 300 }) 189 }.width('100%').padding({ top: 5 }) 190 } 191} 192``` 193 194 195 196### Example 2: Setting the Popup Text Style 197 198This example shows how to use the **bindPopup** API to display a popup with custom **messageOptions** settings. 199 200```ts 201// xxx.ets 202 203@Entry 204@Component 205struct PopupExample { 206 @State handlePopup: boolean = false 207 208 build() { 209 Column({ space: 100 }) { 210 Button('PopupOptions').margin(100) 211 .onClick(() => { 212 this.handlePopup = !this.handlePopup 213 }) 214 .bindPopup(this.handlePopup, { 215 // Popup of the PopupOptions type 216 message: 'This is a popup with PopupOptions', 217 messageOptions: { 218 // Text style of the popup 219 textColor: Color.Red, 220 font: { 221 size: '14vp', 222 style: FontStyle.Italic, 223 weight: FontWeight.Bolder 224 } 225 }, 226 placement: Placement.Bottom, 227 enableArrow: false, // Set the arrow not to display. 228 targetSpace: '15vp', 229 onStateChange: (e) => { 230 console.info(JSON.stringify(e.isVisible)) 231 if (!e.isVisible) { 232 this.handlePopup = false 233 } 234 } 235 }) 236 }.margin(20) 237 } 238} 239``` 240 241 242 243### Example 3: Setting the Popup Style 244 245This example demonstrates how to use the **bindPopup** API with properties like **arrowHeight**, **arrowWidth**, **radius**, **shadow**, and **popupColor** to set the styles for both the popup's arrow and the popup itself. 246 247```ts 248// xxx.ets 249 250@Entry 251@Component 252struct PopupExample { 253 @State customPopup: boolean = false 254 @State handlePopup: boolean = false 255 256 build() { 257 Column({ space: 100 }) { 258 Button("popup") 259 .margin({ top: 50 }) 260 .onClick(() => { 261 this.customPopup = !this.customPopup 262 }) 263 .bindPopup(this.customPopup, { 264 message: "this is a popup", 265 arrowHeight: 20, // Set the height for the popup arrow. 266 arrowWidth: 20, // Set the width for the popup arrow. 267 radius: 20, // Set the corner radius of the popup. 268 shadow: ShadowStyle.OUTER_DEFAULT_XS, // Set the shadow for the popup. 269 }) 270 271 Button('PopupOptions') 272 .onClick(() => { 273 this.handlePopup = !this.handlePopup 274 }) 275 .bindPopup(this.handlePopup, { 276 width: 300, 277 message: 'This is a popup with PopupOptions', 278 arrowPointPosition: ArrowPointPosition.START, // Set the position for the popup arrow. 279 backgroundBlurStyle: BlurStyle.NONE, // Disable the background blur for the popup. 280 popupColor: Color.Red, // Set the background color for the popup. 281 autoCancel: true, 282 }) 283 } 284 .width('100%') 285 } 286} 287``` 288 289 290 291### Example 4: Setting the Popup Animation 292 293In this example, the **bindPopup** API is used with the **transition** property to implement animations for displaying and dismissing popups. 294 295```ts 296// xxx.ets 297@Entry 298@Component 299struct PopupExample { 300 @State handlePopup: boolean = false 301 @State customPopup: boolean = false 302 303 // Popup builder 304 @Builder popupBuilder() { 305 Row() { 306 Text('Custom Popup with transitionEffect').fontSize(10) 307 }.height(50).padding(5) 308 } 309 310 build() { 311 Flex({ direction: FlexDirection.Column }) { 312 // PopupOptions for setting the popup 313 Button('PopupOptions') 314 .onClick(() => { 315 this.handlePopup = !this.handlePopup 316 }) 317 .bindPopup(this.handlePopup, { 318 message: 'This is a popup with transitionEffect', 319 placementOnTop: true, 320 showInSubWindow: false, 321 onStateChange: (e) => { 322 console.info(JSON.stringify(e.isVisible)) 323 if (!e.isVisible) { 324 this.handlePopup = false 325 } 326 }, 327 // Set the popup animation to a combination of opacity and translation effects, with no exit animation. 328 transition:TransitionEffect.asymmetric( 329 TransitionEffect.OPACITY.animation({ duration: 1000, curve: Curve.Ease }).combine( 330 TransitionEffect.translate({ x: 50, y: 50 })), 331 TransitionEffect.IDENTITY) 332 }) 333 .position({ x: 100, y: 150 }) 334 335 // CustomPopupOptions for setting the popup 336 Button('CustomPopupOptions') 337 .onClick(() => { 338 this.customPopup = !this.customPopup 339 }) 340 .bindPopup(this.customPopup, { 341 builder: this.popupBuilder, 342 placement: Placement.Top, 343 showInSubWindow: false, 344 onStateChange: (e) => { 345 if (!e.isVisible) { 346 this.customPopup = false 347 } 348 }, 349 // Set the popup entrance and exit animations to be a scaling effect. 350 transition:TransitionEffect.scale({ x: 1, y: 0 }).animation({ duration: 500, curve: Curve.Ease }) 351 }) 352 .position({ x: 80, y: 300 }) 353 }.width('100%').padding({ top: 5 }) 354 } 355} 356``` 357 358 359 360### Example 5: Adding an Event to a Popup 361 362This example uses the **bindPopup** API with the **onWillDismiss** property to intercept the dismissal event when a popup is about to be dismissed and execute a callback function. 363 364```ts 365// xxx.ets 366 367@Entry 368@Component 369struct PopupExample { 370 @State handlePopup: boolean = false 371 build() { 372 Column() { 373 Button('PopupOptions') 374 .onClick(() => { 375 this.handlePopup = true 376 }) 377 .bindPopup(this.handlePopup, { 378 message: 'This is a popup with PopupOptions', 379 messageOptions: { 380 textColor: Color.Red, 381 font: { 382 size: '14vp', 383 style: FontStyle.Italic, 384 weight: FontWeight.Bolder 385 } 386 }, 387 placement: Placement.Bottom, 388 enableArrow: false, 389 targetSpace: '15vp', 390 onStateChange: (e) => { 391 if (!e.isVisible) { 392 this.handlePopup = false 393 } 394 }, 395 onWillDismiss: ( 396 (dismissPopupAction: DismissPopupAction) => { 397 console.info("dismissReason:" + JSON.stringify(dismissPopupAction.reason)) 398 if (dismissPopupAction.reason == DismissReason.PRESS_BACK) { 399 dismissPopupAction.dismiss() 400 } 401 } 402 ) 403 }) 404 }.margin(20) 405 } 406} 407``` 408 409 410 411### Example 6: Intercepting the Popup Dismissal Event 412 413In this example, the **onWillDismiss** property is set to **false** to intercept the dismissal event of the popup. 414 415```ts 416// xxx.ets 417 418@Entry 419@Component 420struct PopupExample { 421 @State handlePopup: boolean = false 422 build() { 423 Column() { 424 Button('PopupOptions') 425 .onClick(() => { 426 this.handlePopup = true 427 }) 428 .bindPopup(this.handlePopup, { 429 message: 'This is a popup with PopupOptions', 430 messageOptions: { 431 textColor: Color.Red, 432 font: { 433 size: '14vp', 434 style: FontStyle.Italic, 435 weight: FontWeight.Bolder 436 } 437 }, 438 placement: Placement.Bottom, 439 enableArrow: false, 440 targetSpace: '15vp', 441 followTransformOfTarget: true, 442 onStateChange: (e) => { 443 let timer = setTimeout(()=>{this.handlePopup = false},6000) 444 if (!e.isVisible) { 445 this.handlePopup = false 446 clearTimeout(timer) 447 } 448 }, 449 onWillDismiss: false 450 }) 451 }.margin(20) 452 } 453} 454``` 455 456 457