1# Popup 2You can bind the **Popup** attribute to a component to create a popup, specifying its content and interaction logic, and display state. It is mainly used for screen recording and message notification. 3 4Popups can be defined with [PopupOptions](../reference/apis-arkui/arkui-ts/ts-universal-attributes-popup.md#popupoptions) or [CustomPopupOptions](../reference/apis-arkui/arkui-ts/ts-universal-attributes-popup.md#custompopupoptions8). In **PopupOptions**, you can set **primaryButton** and **secondaryButton** to include buttons in the popup. In **CustomPopupOptions**, you can create a custom popup through [builder](../quick-start/arkts-builder.md). 5 6You can configure the modality of a popup through [mask](../reference/apis-arkui/arkui-ts/ts-universal-attributes-popup.md#popupoptions). Setting **mask** to **true** or a color value makes the popup a modal, and setting **mask** to **false** makes the popup a non-modal. 7 8## Creating a Text Popup 9 10Text popups are usually used to display text only and do not allow for user interactions. Bind the **Popup** attribute to a component. When the **show** parameter in the **bindPopup** attribute is set to **true**, a popup is displayed. 11 12If you bind the **Popup** attribute to a **\<Button>** component, each time the **\<Button>** button is clicked, the Boolean value of **handlePopup** changes. When it changes to **true**, the popup is displayed. 13 14```ts 15@Entry 16@Component 17struct PopupExample { 18 @State handlePopup: boolean = false 19 20 build() { 21 Column() { 22 Button('PopupOptions') 23 .onClick(() => { 24 this.handlePopup = !this.handlePopup 25 }) 26 .bindPopup(this.handlePopup, { 27 message: 'This is a popup with PopupOptions', 28 }) 29 }.width('100%').padding({ top: 5 }) 30 } 31} 32``` 33 34 35 36## Adding an Event Listener for Popup State Changes 37 38You can use the **onStateChange** parameter to add an event callback for popup state changes, so as to determine the current state of the popup. 39 40```ts 41@Entry 42@Component 43struct PopupExample { 44 @State handlePopup: boolean = false 45 46 build() { 47 Column() { 48 Button('PopupOptions') 49 .onClick(() => { 50 this.handlePopup = !this.handlePopup 51 }) 52 .bindPopup(this.handlePopup, { 53 message: 'This is a popup with PopupOptions', 54 onStateChange: (e)=> {// Return the current popup state. 55 if (!e.isVisible) { 56 this.handlePopup = false 57 } 58 } 59 }) 60 }.width('100%').padding({ top: 5 }) 61 } 62} 63``` 64 65 66 67## Creating a Popup with Buttons 68 69You can add a maximum of two buttons to a popup through the **primaryButton** and **secondaryButton** attributes. For each of the buttons, you can set the **action** parameter to specify the operation to be triggered. 70 71```ts 72@Entry 73@Component 74struct PopupExample22 { 75 @State handlePopup: boolean = false 76 77 build() { 78 Column() { 79 Button('PopupOptions').margin({ top: 200 }) 80 .onClick(() => { 81 this.handlePopup = !this.handlePopup 82 }) 83 .bindPopup(this.handlePopup, { 84 message: 'This is a popup with PopupOptions', 85 primaryButton: { 86 value: 'Confirm', 87 action: () => { 88 this.handlePopup = !this.handlePopup 89 console.info('confirm Button click') 90 } 91 }, 92 secondaryButton: { 93 value: 'Cancel', 94 action: () => { 95 this.handlePopup = !this.handlePopup 96 } 97 }, 98 onStateChange: (e) => { 99 if (!e.isVisible) { 100 this.handlePopup = false 101 } 102 } 103 }) 104 }.width('100%').padding({ top: 5 }) 105 } 106} 107``` 108 109 110 111## Implementing Popup Animation 112 113You implement the entrance and exit animation effects of popups through **transition**. 114 115```ts 116// xxx.ets 117@Entry 118@Component 119struct PopupExample { 120 @State handlePopup: boolean = false 121 @State customPopup: boolean = false 122 123 // Define the popup content in the popup builder. 124 @Builder popupBuilder() { 125 Row() { 126 Text('Custom Popup with transitionEffect').fontSize(10) 127 }.height(50).padding(5) 128 } 129 130 build() { 131 Flex({ direction: FlexDirection.Column }) { 132 // PopupOptions for setting the popup 133 Button('PopupOptions') 134 .onClick(() => { 135 this.handlePopup = !this.handlePopup 136 }) 137 .bindPopup(this.handlePopup, { 138 message: 'This is a popup with transitionEffect', 139 placementOnTop: true, 140 showInSubWindow: false, 141 onStateChange: (e) => { 142 if (!e.isVisible) { 143 this.handlePopup = false 144 } 145 }, 146 // Set the popup animation to a combination of opacity and translation effects, with no exit animation. 147 transition:TransitionEffect.asymmetric( 148 TransitionEffect.OPACITY.animation({ duration: 1000, curve: Curve.Ease }).combine( 149 TransitionEffect.translate({ x: 50, y: 50 })), 150 TransitionEffect.IDENTITY) 151 }) 152 .position({ x: 100, y: 150 }) 153 154 // CustomPopupOptions for setting the popup 155 Button('CustomPopupOptions') 156 .onClick(() => { 157 this.customPopup = !this.customPopup 158 }) 159 .bindPopup(this.customPopup, { 160 builder: this.popupBuilder, 161 placement: Placement.Top, 162 showInSubWindow: false, 163 onStateChange: (e) => { 164 if (!e.isVisible) { 165 this.customPopup = false 166 } 167 }, 168 // Set the popup entrance and exit animations to be a scaling effect. 169 transition:TransitionEffect.scale({ x: 1, y: 0 }).animation({ duration: 500, curve: Curve.Ease }) 170 }) 171 .position({ x: 80, y: 300 }) 172 }.width('100%').padding({ top: 5 }) 173 } 174} 175``` 176 177 178 179## Creating a Custom Popup 180 181You can create a custom popup with **builder** in **CustomPopupOptions**, defining custom content in \@Builder. In addition, you can use parameters such as **popupColor** to control the popup style. 182 183```ts 184@Entry 185@Component 186struct Index { 187 @State customPopup: boolean = false 188 // Define the popup content in the popup builder. 189 @Builder popupBuilder() { 190 Row({ space: 2 }) { 191 Image($r("app.media.icon")).width(24).height(24).margin({ left: 5 }) 192 Text('This is Custom Popup').fontSize(15) 193 }.width(200).height(50).padding(5) 194 } 195 build() { 196 Column() { 197 Button('CustomPopupOptions') 198 .position({x:100,y:200}) 199 .onClick(() => { 200 this.customPopup = !this.customPopup 201 }) 202 .bindPopup(this.customPopup, { 203 builder: this.popupBuilder, // Content of the popup. 204 placement:Placement.Bottom, // Position of the popup. 205 popupColor:Color.Pink // Background color of the popup. 206 onStateChange: (e) => { 207 if (!e.isVisible) { 208 this.customPopup = false 209 } 210 } 211 }) 212 } 213 .height('100%') 214 } 215} 216``` 217 218To place the popup in a specific position, set the **placement** parameter. The popup builder triggers a popup message to instruct the user to complete the operation. 219 220 221 222## Defining the Popup Style 223 224You can define the popup style using both builder-based customization and through specific API configurations. 225 226Background color: While popups initially come with a transparent background, they have a blur effect, which is **COMPONENT_ULTRA_THICK** on phones. 227Mask style: Popups come with a default mask that is transparent. 228Size: The size of a popup is determined by the content within the builder or the length of the message it holds. 229Position: Popups are located below their host component by default. You can control the display position and alignment using the **Placement** API. 230The following example demonstrates how to configure a popup's style using **popupColor**, **mask**, **width**, and **placement**. 231 232```ts 233// xxx.ets 234 235@Entry 236@Component 237struct PopupExample { 238 @State handlePopup: boolean = false 239 240 build() { 241 Column({ space: 100 }) { 242 Button('PopupOptions') 243 .onClick(() => { 244 this.handlePopup = !this.handlePopup 245 }) 246 .bindPopup(this.handlePopup, { 247 width: 200, 248 message: 'This is a popup.', 249 popupColor: Color.Red, // Set the background color for the popup. 250 mask: { 251 color: '#33d9d9d9' 252 }, 253 placement: Placement.Top, 254 backgroundBlurStyle: BlurStyle.NONE // Remove the blur effect for the popup. 255 }) 256 } 257 .width('100%') 258 } 259} 260``` 261 262 263