1# Sheet Transition
2
3You can bind a sheet to a component through the **bindSheet** attribute. You can also set the sheet to the preset or custom height for when the component is inserted.
4
5>  **NOTE**
6>
7>  This feature is supported since API version 10. Updates will be marked with a superscript to indicate their earliest API version.
8>
9>  Route hopping is not supported.
10
11## bindSheet
12
13bindSheet(isShow: Optional\<boolean\>, builder: CustomBuilder, options?: SheetOptions)
14
15Binds a sheet to the component, which is displayed when the component is touched.
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| isShow  | Optional\<boolean\>                          | Yes  | Whether to display the sheet.<br>Since API version 10, this parameter supports two-way binding through [$$](../../../quick-start/arkts-two-way-sync.md).|
26| builder | [CustomBuilder](ts-types.md#custombuilder8) | Yes  | Content of the sheet.                                        |
27| options | [SheetOptions](#sheetoptions)               | No  | Optional attributes of the sheet.                                  |
28
29> **NOTE**
30>
31> 1. When no two-way binding is set up for the **isShow** parameter, closing the sheet by dragging does not change the parameter value.
32>
33> 2. To synchronize the value of the **isShow** parameter with the sheet UI state, set up a two-way binding for **isShow** through [$$](../../../quick-start/arkts-two-way-sync.md).
34>
35> 3. In scenarios where a sheet with a single detent is dragged upwards or a sheet with multiple detents is shifted to another detent by swiping up, the display area is updated after the drag ends or the shift is completed.
36>
37> 4. A sheet is a popup that is strictly bound to its host node. To achieve an effect where the sheet appears the moment the page is displayed, ensure that the host node is mounted in the view hierarchy. If the host node is not yet mounted when **isShow** is set to **true**, the sheet will not be displayed. You are advised to use the [onAppear](ts-universal-events-show-hide.md#onappear) to ensure that the sheet is shown after the host node is mounted.
38> When [SheetMode](#sheetmode12) is set to **EMBEDDED**, in addition to the host node, also ensure that the corresponding page node is successfully mounted.
39>
40> 5. The exit animation of the sheet does not support interruption, and the sheet cannot respond to other gestures during the execution. The current exit animation uses a [spring curve](../../../ui/arkts-spring-curve.md), which has a subtle trailing effect that is not visually prominent. Therefore, when the sheet exits, although it may appear to have disappeared, the animation might not have fully finished, and attempting to initiate the sheet again by a touch will not work. You must wait for the animation to fully complete before you can initiate the sheet again.
41>
42## SheetOptions
43
44Inherits [BindOptions](#bindoptions).
45
46| Name             | Type                                      | Mandatory  | Description             |
47| --------------- | ---------------------------------------- | ---- | --------------- |
48| height          | [SheetSize](#sheetsize) \| [Length](ts-types.md#length) | No   | Height of the sheet.<br>Default value: **LARGE**<br>**NOTE**<br>In versions earlier than API version 12, this attribute is ineffective for a bottom sheet in landscape mode; the height is fixed at 8 vp from the top of the screen.<br>Since API version 12, this attribute takes effect for a bottom sheet in landscape mode; the maximum height is 8 vp from the top of the screen.<br>Since API version 14, for a bottom sheet in landscape mode, the maximum height is 8 vp from the top of the screen if there is no status bar, and 8 vp from the status bar if there is one.<br>When a bottom sheet has **detents** set, this attribute is ineffective.<br>For a bottom sheet in portrait mode, the maximum height is 8 vp from the status bar.<br>For center and popup sheets set to **SheetSize.LARGE** or **SheetSize.MEDIUM**, this attribute is ineffective, with the default height being 560 vp. For center and popup sheets, the minimum height is 320 vp, and the maximum height is 90% of the shorter edge of the window. If the height specified by **Length** and the height adaptively set with **SheetSize.FIT_CONTENT** exceed the maximum height, the maximum height is used instead. If they are less than the minimum height, the minimum height is used instead.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
49| detents<sup>11+</sup> | [([SheetSize](#sheetsize) \| [Length](ts-types.md#length)), ( [SheetSize](#sheetsize) \| [Length](ts-types.md#length))?, ([SheetSize](#sheetsize) \| [Length](ts-types.md#length))?] | No| Array of heights where the sheet can rest.<br>**NOTE**<br>Since API version 12, this attribute takes effect for a bottom sheet in landscape mode.<br>In earlier versions, this attribute takes effect only for the bottom sheet in portrait mode. The first height in the tuple is the initial height.<br>The sheet can switch between heights by dragging. After the sheet is dragged and released, it switches to the target height or remains at the current height, depending on the velocity and distance.<br> If the velocity exceeds the threshold, the sheet switches to the target height in the same direction as the velocity. If the velocity is less than the threshold, the displacement distance is used for judgement. If the displacement distance is greater than 1/2 of the distance between the current and target positions, the sheet switches to the target height in the same direction as the velocity; otherwise, the sheet remains at the current height.<br> Velocity threshold: 1000; Distance threshold: 50%.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
50| preferType<sup>11+</sup> | [SheetType](#sheettype11)| No| Type of the sheet.<br>**NOTE**<br>The types supported by the sheet vary by window.<br>1. Width < 600 vp: bottom<br>2. 600 vp <= width < 840 vp: bottom and center (default)<br>3. Width >= 840 vp: bottom, center, and popup (default)<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
51| showClose<sup>11+</sup> | boolean \| [Resource](ts-types.md#resource) | No| Whether to display the close icon. By default, the icon is displayed.<br> On 2-in-1 devices, the icon does not have a background by default.<br>**NOTE**<br>The value of **Resource** must be of the Boolean type.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
52| dragBar         | boolean                                  | No   | Whether to display the drag bar.<br>**NOTE**<br>By default, the drag bar is displayed only when the sheet's **detents** attribute is set to multiple heights and the settings take effect.  <br>**Atomic service API**: This API can be used in atomic services since API version 11.|
53| blurStyle<sup>11+</sup> | [BlurStyle](ts-universal-attributes-background.md#blurstyle9) | No| Background blur of the sheet. By default, there is no background blur.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
54| maskColor | [ResourceColor](ts-types.md#resourcecolor) | No| Mask color of the sheet.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
55| title<sup>11+</sup> | [SheetTitleOptions](#sheettitleoptions11) \| [CustomBuilder](ts-types.md#custombuilder8) | No| Title of the sheet.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
56| enableOutsideInteractive<sup>11+</sup> | boolean | No| Whether to allow users to interact with the page pertaining to the sheet.<br>**NOTE**<br>The value **true** means that interactions are allowed, in which case no mask is not displayed. The value **false** means that interactions are not allowed, in which case a mask is displayed. If this parameter is not set, interactions are allowed for the popup sheet, but not for bottom and center sheets. If this parameter is set to **true**, the setting of **maskColor** does not take effect.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
57| shouldDismiss<sup>11+</sup> | (sheetDismiss: [SheetDismiss](#sheetdismiss11)) => void | No| Callback invoked when the user performs an interactive dismiss operation: pulling down or clicking the back button, the mask, or the close icon.<br>**NOTE**<br>If this callback is registered, the sheet is not dismissed immediately when the user performs the above operations. To dismiss the sheet, you must call **shouldDismiss.dismiss()** in the callback.<br>If this callback is not registered, the sheet is dismissed immediately when the user performs the above operations, without any additional behavior.<br>It is recommended that this API be used in scenarios where a [secondary confirmation](../../../ui/arkts-sheet-page.md#secondary-confirmation-capability) is required<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
58| onWillDismiss<sup>12+</sup> | [DismissSheetAction](#dismisssheetaction12) | No   | Callback invoked when the user performs an interactive dismiss operation: pulling down or clicking the back button, the mask, or the close icon, to obtain the type of dismiss operation and decide whether to dismiss the sheet.<br>**NOTE**<br>If this callback is registered, the sheet is not dismissed immediately when the user performs the above operations. Instead,you can use the [reason](../js-apis-promptAction.md#dismissreason12) parameter in the callback to determine the type of dismiss operation and decide whether to dismiss the sheet.<br>If this callback is not registered, the sheet is dismissed immediately when the user performs the above operations, without any additional behavior.<br>No further interception with **onWillDismiss** is allowed in an **onWillDismiss** callback.<br>It is recommended that this API be used in scenarios where a [secondary confirmation](../../../ui/arkts-sheet-page.md#secondary-confirmation-capability) is required<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
59| onWillSpringBackWhenDismiss<sup>12+</sup> | [SpringBackAction](#springbackaction12) | No   | Callback invoked when the user performs a pull-down-to-dismiss gesture, to control the bounce effect.<br>**NOTE**<br>If this callback is registered along with **shouldDismiss** or **onWillDismiss**,you can control whether the sheet bounces back during the pull-down-to-dismiss operation by calling **springBack** in the callback.<br>If this callback is not registered but **shouldDismiss** or **onWillDismiss** is registered, the sheet will bounce back before remaining open or being dismissed based on the callback behavior.<br>If neither this callback nor **shouldDismiss** or **onWillDismiss** is registered, the sheet is dismissed by default during the pull-down-to-dismiss operation.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
60| onHeightDidChange<sup>12+</sup> | Callback&lt;number&gt; | No| Callback for changes in the height of the sheet.<br>**NOTE**<br>For a bottom sheet, the height of each frame is only returned when there are changes in detents or during drag actions. When the sheet is pulled up or making space for the soft keyboard, only the final height is returned. For other types of sheets, the final height is only returned when the sheet is pulled up.<br>The return value is in px.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
61| onDetentsDidChange<sup>12+</sup> | Callback&lt;number&gt; | No| Callback for changes in the detents of the sheet.<br>**NOTE**<br>For a bottom sheet, the final height is returned when there are changes in detents.<br>The return value is in px.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
62| onWidthDidChange<sup>12+</sup> | Callback&lt;number&gt; | No| Callback for changes in the width of the sheet.<br>**NOTE**<br>The final height is returned when there are changes in the width.<br>The return value is in px.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
63| onTypeDidChange<sup>12+</sup> | Callback&lt;[SheetType](#sheettype11)&gt;| No| Callback for changes in the type of the sheet.<br>**NOTE**<br>The final type is returned when there are changes in the type.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
64| borderWidth<sup>12+</sup> | [Dimension](ts-types.md#dimension10) \| [EdgeWidths](ts-types.md#edgewidths9) \| [LocalizedEdgeWidths](ts-types.md#localizededgewidths12)<sup>12+</sup>  | No| Border width of the sheet.<br>You can set the width for all four sides or set separate widths for individual sides.<br>Default value: **0**<br> Percentage parameter method: Set the border width of the sheet as a percentage of the width of the parent element.<br>If the left and right border widths of the sheet are greater than the width of the sheet, and the top and bottom border widths are greater than the height of the sheet, the display may not appear as expected.<br>**NOTE**<br>For bottom sheets, the bottom border width setting is ineffective.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
65| borderColor<sup>12+</sup> | [ResourceColor](ts-types.md#resourcecolor) \| [EdgeColors](ts-types.md#edgecolors9) \| [LocalizedEdgeColors](ts-types.md#localizededgecolors12)<sup>12+</sup>  | No| Border color of the sheet.<br>Default value: **Color.Black**<br> **borderColor** must be used with **borderWidth** in pairs.<br>**NOTE**<br>For bottom sheets, the bottom border color setting is ineffective.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
66| borderStyle<sup>12+</sup> | [BorderStyle](ts-appendix-enums.md#borderstyle) \| [EdgeStyles](ts-types.md#edgestyles9)  | No| Border style of the sheet.<br>Default value: **BorderStyle.Solid**<br> **borderStyle** must be used with **borderWidth** in pairs.<br>**NOTE**<br>For bottom sheets, the bottom border style setting is ineffective.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
67| width<sup>12+</sup> | [Dimension](ts-types.md#dimension10)   | No| Width of the sheet.<br> Percentage parameter method: Set the width of the sheet as a percentage of the width of the parent element. <br>**Atomic service API**: This API can be used in atomic services since API version 12.|
68| shadow<sup>12+</sup> | [ShadowOptions](ts-universal-attributes-image-effect.md#shadowoptions) \| [ShadowStyle](ts-universal-attributes-image-effect.md#shadowstyle10)   | No| Shadow of the sheet.<br>Default value for 2-in-1 devices: **ShadowStyle.OUTER_FLOATING_SM**<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
69| uiContext<sup>12+</sup> | [UIContext](../js-apis-arkui-UIContext.md#uicontext)   | No| **UIContext** instance corresponding to the window where the sheet is displayed.<br>**NOTE**<br>The sheet launched with [openBindSheet](../js-apis-arkui-UIContext.md#openbindsheet12) does not support setting or updating this attribute.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
70| mode<sup>12+</sup> | [SheetMode](#sheetmode12)   | No| Display mode of the sheet.<br>Default value: **SheetMode.OVERLAY**<br>**NOTE**<br> 1. During the display of the sheet, the **mode** attribute does not support dynamic changes. The display hierarchy of the two modes is entirely different, making it impossible to switch a sheet from one mode to another while it is being displayed. You are advised to clearly define and fix the **mode** value to ensure consistency in the display hierarchy.<br> 2. The **UIContext** attribute cannot be set when **SheetMode.EMBEDDED** is set, as their corresponding sheet display hierarchy effects are mutually conflicting.<br>3. For a sheet launched with [openBindSheet](../js-apis-arkui-UIContext.md#openbindsheet12), if a valid target ID is not provided, **SheetMode.EMBEDDED** cannot be set, and the default value **SheetMode.OVERLAY** is used.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
71| scrollSizeMode<sup>12+</sup> | [ScrollSizeMode](#scrollsizemode12)   | No| Timing for updating the content display area of the sheet when it is scrolled.<br>Default value: **ScrollSizeMode.FOLLOW_DETENT**|
72| keyboardAvoidMode<sup>13+</sup> | [SheetKeyboardAvoidMode](#sheetkeyboardavoidmode13) | No| How the sheet avoids the soft keyboard when it is brought up.<br> Default value: **TRANSLATE_AND_SCROLL**<br>**Atomic service API**: This API can be used in atomic services since API version 13.|
73| enableHoverMode<sup>14+</sup>              | boolean | No  | Whether to enable the hover mode.<br>Default value: **false**, meaning not to enable the hover mode.<br>**NOTE**<br>The bottom and popup sheets do not respond in the hover mode.|
74| hoverModeArea<sup>14+</sup>              | [HoverModeAreaType](ts-appendix-enums.md#hovermodeareatype14) | No  | Display area of the dialog box in hover mode.<br>Default value: **HoverModeAreaType.BOTTOM_SCREEN**|
75
76## SheetSize
77
78| Name                     | Value   | Description                        |
79| ------------------------- | ---- | -------------------------------- |
80| MEDIUM                    | 0    | The sheet height is half of the screen height.<br>**Atomic service API**: This API can be used in atomic services since API version 11.  |
81| LARGE                     | 1    | The sheet height is almost the screen height.<br>**Atomic service API**: This API can be used in atomic services since API version 11.  |
82| FIT_CONTENT<sup>11+</sup> | 2    | The sheet height automatically adapts to the content.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
83
84## BindOptions
85
86| Name           | Type                                      | Mandatory| Description                    |
87| --------------- | ------------------------------------------ | ---- | ------------------------ |
88| backgroundColor | [ResourceColor](ts-types.md#resourcecolor) | No  | Background color of the sheet.<br>Default value: **Color.White**<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
89| onWillAppear<sup>12+</sup>        | () => void                                 | No  | Callback for when the sheet is about to be displayed (before the animation starts). **Atomic service API**: This API can be used in atomic services since API version 12.|
90| onAppear        | () => void                                 | No  | Callback for when the sheet is displayed (after the animation ends).<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
91| onWillDisappear<sup>12+</sup>     | () => void                                 | No  | Callback for when the sheet is about to disappear (before the animation starts).<br>**NOTE**<br>Modifying state variables within the **onWillDisappear** function is not allowed, as it may lead to unstable component behavior. **Atomic service API**: This API can be used in atomic services since API version 12.|
92| onDisappear     | () => void                                 | No  | Callback for when the sheet disappears (after the animation ends).<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
93
94## SheetType<sup>11+</sup>
95
96**Atomic service API**: This API can be used in atomic services since API version 12.
97
98| Name  | Value  | Description                                              |
99| ------ | ---- | ------------------------------------------------------ |
100| BOTTOM | 0    | Bottom sheet.                                            |
101| CENTER | 1    | Center sheet.                                            |
102| POPUP  | 2    | Popup sheet. The popup sheet cannot be dismissed with a pull-down gesture.|
103
104## SheetDismiss<sup>11+</sup>
105
106**Atomic service API**: This API can be used in atomic services since API version 12.
107
108| Name   | Type      | Mandatory| Description                                                        |
109| ------- | ---------- | ---- | ------------------------------------------------------------ |
110| dismiss | () => void | Yes  | Callback for dismissing the sheet. Call this API only when you need the sheet to exit.|
111
112## SheetTitleOptions<sup>11+</sup>
113
114**Atomic service API**: This API can be used in atomic services since API version 12.
115
116| Name    | Type                                  | Mandatory| Description                |
117| -------- | -------------------------------------- | ---- | -------------------- |
118| title    | [ResourceStr](ts-types.md#resourcestr) | Yes  | Main title of the sheet.|
119| subtitle | [ResourceStr](ts-types.md#resourcestr) | No  | Subtitle of the sheet.|
120
121## SheetMode<sup>12+</sup>
122
123**Atomic service API**: This API can be used in atomic services since API version 12.
124
125| Name                     | Value  | Description                        |
126| ------------------------- | ---- | -------------------------------- |
127| OVERLAY                   | 0    | The sheet is displayed at the top of the window corresponding to the current **UIContext** instance, above all pages. It is displayed at the same level as dialog boxes.  |
128| EMBEDDED                  | 1    | The sheet is displayed at the top of the current page.<br>**NOTE**<br>Currently, the sheet can only be mounted on a **Page** or **NavDestination** node, with priority given to the **NavDestination** node if it is present. This means that, the sheet can only be displayed at the top of these two types of pages.<br> In this mode, new pages can overlay the sheet, and when the user returns to the previous page, the sheet remains present without losing its content.<br> In this mode, you must ensure that the target page node, such as the **Page** node, has been attached to the tree before bringing up the sheet; otherwise, the sheet will not be able to be attached to the corresponding page node.|
129
130## ScrollSizeMode<sup>12+</sup>
131| Name          | Value  | Description                        |
132| ------------------------- | ---- | -------------------------------- |
133| FOLLOW_DETENT | 0    | The sheet updates the content display area after a swipe ends.  |
134| CONTINUOUS    | 1    | The sheet continuously updates the content display area during the scroll process.|
135
136## DismissSheetAction<sup>12+</sup>
137
138**Atomic service API**: This API can be used in atomic services since API version 12.
139
140| Name             | Type                                      | Mandatory  | Description           |
141| --------------- | ---------------------------------------- | ---- | ------------- |
142| dismiss | function | Yes   | Callback for dismissing the sheet. Call this API when you need to exit the page.|
143| reason | [DismissReason](../js-apis-promptAction.md#dismissreason12) | Yes   | Type of operation that causes the sheet to be dismissed. |
144
145## SpringBackAction<sup>12+</sup>
146
147| Name             | Type                                      | Mandatory  | Description           |
148| --------------- | ---------------------------------------- | ---- | ------------- |
149| springBack | function | Yes   | Callback to control the interactive spring back before the sheet is dismissed. |
150
151## SheetKeyboardAvoidMode<sup>13+</sup>
152
153| Name          | Value  | Description                        |
154| ------------------------- | ---- | -------------------------------- |
155| NONE | 0    | Disables keyboard avoidance for the sheet.  |
156| TRANSLATE_AND_RESIZE    | 1    | Lifts the sheet to avoid the keyboard;<br>if not enough, resizes the content.|
157| RESIZE_ONLY    | 2    | Resizes the content to avoid the keyboard.|
158| TRANSLATE_AND_SCROLL    | 3    | Lifts the sheet to avoid the keyboard;<br>if not enough, scrolls the content.|
159
160## Example
161### Example 1: Setting Sheets with Different Heights
162
163This example demonstrates how to set different heights for sheets using the **height** property.
164
165```ts
166// xxx.ets
167@Entry
168@Component
169struct SheetTransitionExample {
170  @State isShow: boolean = false
171  @State isShow2: boolean = false
172  @State sheetHeight: number = 300;
173
174  @Builder
175  myBuilder() {
176    Column() {
177      Button("change height")
178        .margin(10)
179        .fontSize(20)
180        .onClick(() => {
181          this.sheetHeight = 500;
182        })
183
184      Button("Set Illegal height")
185        .margin(10)
186        .fontSize(20)
187        .onClick(() => {
188          this.sheetHeight = -1;
189        })
190
191      Button("close modal 1")
192        .margin(10)
193        .fontSize(20)
194        .onClick(() => {
195          this.isShow = false;
196        })
197    }
198    .width('100%')
199    .height('100%')
200  }
201
202  build() {
203    Column() {
204      Button("transition modal 1")
205        .onClick(() => {
206          this.isShow = true
207        })
208        .fontSize(20)
209        .margin(10)
210        .bindSheet($$this.isShow, this.myBuilder(), {
211          height: this.sheetHeight,
212          backgroundColor: Color.Green,
213          onWillAppear: () => {
214            console.log("BindSheet onWillAppear.")
215          },
216          onAppear: () => {
217            console.log("BindSheet onAppear.")
218          },
219          onWillDisappear: () => {
220            console.log("BindSheet onWillDisappear.")
221          },
222          onDisappear: () => {
223            console.log("BindSheet onDisappear.")
224          }
225        })
226    }
227    .justifyContent(FlexAlign.Center)
228    .width('100%')
229    .height('100%')
230  }
231}
232```
233
234![en-us_sheet](figures/en-us_sheet1.gif)
235
236### Example 2: Setting Three Different Height Detents
237
238This example demonstrates how to use the **detents** property of **bindSheet** to set three different height detents for a sheet.
2391. The drag bar is only effective when there are multiple height detents.
2402. Unlike the **height** property, which can set different heights at different times, the **detents** property provides a gesture to switch between detent heights and is more suitable for fixed height intervals.
2413. If the height range is uncertain or there may be more than three different heights, avoid using the **detents** property.
242
243```ts
244// xxx.ets
245@Entry
246@Component
247struct SheetTransitionExample {
248  @State isShow: boolean = false
249
250  @Builder
251  myBuilder() {
252    Column() {
253      Button("content1")
254        .margin(10)
255        .fontSize(20)
256
257      Button("content2")
258        .margin(10)
259        .fontSize(20)
260    }
261    .width('100%')
262  }
263
264  build() {
265    Column() {
266      Button("transition modal 1")
267        .onClick(() => {
268          this.isShow = true
269        })
270        .fontSize(20)
271        .margin(10)
272        .bindSheet($$this.isShow, this.myBuilder(), {
273          detents: [SheetSize.MEDIUM, SheetSize.LARGE, 200],
274          backgroundColor: Color.Gray,
275          blurStyle: BlurStyle.Thick,
276          showClose: true,
277          title: { title: "title", subtitle: "subtitle" },
278        })
279    }
280    .justifyContent(FlexAlign.Start)
281    .width('100%')
282    .height('100%')
283  }
284}
285```
286
287![en-us_sheet](figures/en-us_sheet2.gif)
288
289### Example 3: Setting the Border Width and Color
290
291This example demonstrates how to use the **borderWidth** and **borderColor** properties with **LocalizedEdgeWidths** and **LocalizedEdgeColors** types in **bindSheet**.
292
293```ts
294// xxx.ets
295import { LengthMetrics } from '@kit.ArkUI'
296
297@Entry
298@Component
299struct SheetTransitionExample {
300  @State isShow: boolean = false
301
302  @Builder
303  myBuilder() {
304    Column() {
305      Button("content1")
306        .margin(10)
307        .fontSize(20)
308
309      Button("content2")
310        .margin(10)
311        .fontSize(20)
312    }
313    .width('100%')
314  }
315
316  build() {
317    Column() {
318      Button("transition modal 1")
319        .onClick(() => {
320          this.isShow = true
321        })
322        .fontSize(20)
323        .margin(10)
324        .bindSheet($$this.isShow, this.myBuilder(), {
325          detents: [SheetSize.MEDIUM, SheetSize.LARGE, 200],
326          backgroundColor: Color.Gray,
327          blurStyle: BlurStyle.Thick,
328          showClose: true,
329          title: { title: "title", subtitle: "subtitle" },
330          borderWidth: { top: LengthMetrics.vp(10), start: LengthMetrics.vp(10), end: LengthMetrics.vp(20) },
331          borderColor: { top: Color.Pink, start: Color.Blue, end: Color.Yellow },
332        })
333    }
334    .justifyContent(FlexAlign.Start)
335    .width('100%')
336    .height('100%')
337  }
338}
339```
340
341The following shows how the example is represented with left-to-right scripts.
342
343![en-us_sheet](figures/en-us_sheet3_ltr.png)
344
345The following shows how the example is represented with right-to-left scripts.
346
347![en-us_sheet](figures/en-us_sheet3_rtl.png)
348
349### Example 4: Using Dismiss Callbacks
350
351This example shows how to register **onWillDismiss** and **onWillSpringBackWhenDismiss** with **bindSheet**.
352
353```ts
354// xxx.ets
355@Entry
356@Component
357struct bindSheetExample {
358  @State isShow: Boolean = false;
359
360  @Builder
361  myBuilder() {
362    Column() {
363      Button() {
364        Text("CONTEXT")
365      }.height(50)
366    }
367  }
368
369  build() {
370    Column() {
371      Button("NoRegisterSpringback")
372        .onClick(() => {
373          this.isShow = true
374        })
375        .fontSize(20)
376        .margin(10)
377        .bindSheet($$this.isShow, this.myBuilder(), {
378          height: SheetSize.MEDIUM,
379          blurStyle: BlurStyle.Thick,
380          showClose: true,
381          title: { title: "title", subtitle: "subtitle" },
382          preferType: SheetType.CENTER,
383
384
385          onWillDismiss: ((DismissSheetAction: DismissSheetAction) => {
386            if (DismissSheetAction.reason == DismissReason.SLIDE_DOWN) {
387              DismissSheetAction.dismiss() // Register the dismiss behavior.
388            }
389          }),
390
391          onWillSpringBackWhenDismiss: ((SpringBackAction: SpringBackAction) => {
392            // If springBack is not registered, the sheet will not exhibit a spring back effect when pulled down.
393            //SpringBackAction.springBack()
394          }),
395        })
396    }
397  }
398}
399```
400![en-us_sheet](figures/en-us_sheet4.gif)
401
402### Example 5: Setting Content Update Timing
403
404This example shows how to use **ScrollSizeMode.CONTINUOUS**, which continuously updates the content and is suitable for detents with multiple height settings.
405Whenever possible, minimize UI loading time within the builder, as real-time content refreshing during scrolling has higher performance requirements.
406
407```ts
408// xxx.ets
409@Entry
410@Component
411struct Index {
412  @State isShow: boolean = false;
413
414  @Builder
415  myBuilder() {
416    Column() {
417      Column()
418        .backgroundColor(Color.Blue)
419        .height(200)
420        .width('100%')
421      Column()
422        .backgroundColor(Color.Green)
423        .height(200)
424        .width('100%')
425    }
426  }
427
428  build() {
429    Column() {
430      Button('BindSheet')
431        .onClick(() => {
432          this.isShow = true;
433        })
434        .bindSheet($$this.isShow, this.myBuilder(), {
435          detents: [300, 600, 900],
436          uiContext: this.getUIContext(),
437          mode: SheetMode.OVERLAY,
438          scrollSizeMode: ScrollSizeMode.CONTINUOUS,
439          backgroundColor: Color.Orange,
440          title: { title: 'Title', subtitle: 'Subtitle' }
441        })
442    }
443    .justifyContent(FlexAlign.Center)
444    .width('100%')
445    .height('100%')
446  }
447}
448```
449The sheet's content height is not updated until the user stops dragging and releases the sheet.
450
451![en-us_sheet](figures/en-us_sheet5_ltr.gif)
452
453The sheet's content height is updated in real time as the user drags the sheet.
454
455![en-us_sheet](figures/en-us_sheet5_rtl.gif)
456
457### Example 6: Listening for Keyboard Height Changes
458
459This example shows how to listen for keyboard height changes and adjust the scroll of a scrollable component based on these changes in **resizeOnly** mode.
460
461```ts
462//xxx.ets
463import { window } from '@kit.ArkUI';
464import { BusinessError } from '@kit.BasicServicesKit';
465
466@Entry
467@Component
468struct ListenKeyboardHeightChange {
469  @State isShow: boolean = false;
470  @State avoidMode: SheetKeyboardAvoidMode = SheetKeyboardAvoidMode.RESIZE_ONLY;
471  scroller = new Scroller();
472  private arr: number[] = [0, 1, 2, 3, 4, 5, 6];
473  @State scrollHeight: number = 0;
474  @State keyBoardChange: boolean = false;
475  windowClass: window.Window | undefined = undefined;
476
477  aboutToAppear(): void {
478    try {
479      window.getLastWindow(getContext(this), (err: BusinessError, data) => {
480        const errCode: number = err.code;
481        if (errCode) {
482          console.error(`Failed to obtain the top window, Cause code: ${err.code}, message: ${err.message}`);
483          return;
484        }
485        this.windowClass = data;
486        try {
487          if (this.windowClass !== undefined) {
488            console.log('success in listen height change');
489            // Register a listener for keyboard height changes.
490            this.windowClass.on('keyboardHeightChange', this.callback);
491          }
492        } catch (exception) {
493          console.error(`Failed to enable the listener for keyboard height changes, Cause code: ${exception.code}, message: ${exception.message}`);
494        }
495        console.info('Succeeded in obtaining the top window. Data: ' + JSON.stringify(data));
496      });
497    } catch (exception) {
498      console.error(`Failed to obtain the top window, Cause code: ${exception.code}, message: ${exception.message}`);
499    }
500  }
501
502  // Set the flag when keyboard height changes.
503  callback = (height: number) => {
504    this.scrollHeight = height;
505    console.log('height change: ' + this.scrollHeight);
506    if (height !== 0) {
507      this.keyBoardChange = true;
508    }
509  }
510  // Trigger scroll when the scrollable component height changes based on the flag.
511  sizeChangeCallback = (oldValue: SizeOptions, newValue: SizeOptions) => {
512    if (this.keyBoardChange) {
513      this.scroller.scrollBy(0, this.scrollHeight);
514      this.keyBoardChange = false;
515    }
516  }
517
518  @Builder
519  myBuilder() {
520    Scroll(this.scroller) {
521      Column() {
522        ForEach(this.arr, (item: number) => {
523          Row() {
524            Text(item.toString())
525              .width('80%')
526              .height(60)
527              .backgroundColor('#3366CC')
528              .borderRadius(15)
529              .fontSize(16)
530              .textAlign(TextAlign.Center)
531              .margin({ top: 5 })
532          }
533        }, (item: number) => item.toString())
534
535        TextInput().height('100')
536
537        Flex({ alignItems: ItemAlign.End }) {
538          Row() {
539            Button("click")
540              .margin(10)
541              .fontSize(20)
542              .width('45%')
543
544            Button("cancel")
545              .margin(10)
546              .fontSize(20)
547              .width('45%')
548          }.width('100%')
549        }.height('100%')
550      }.margin({ right: 15 })
551    }
552    .scrollBar(BarState.On)
553    .scrollable(ScrollDirection.Vertical)
554    .onSizeChange(this.sizeChangeCallback)
555  }
556
557  build() {
558    Column() {
559      Button("transition modal 1")
560        .onClick(() => {
561          this.isShow = true
562        })
563        .fontSize(20)
564        .margin(10)
565        .bindSheet($$this.isShow, this.myBuilder(), {
566          detents: [SheetSize.MEDIUM, SheetSize.LARGE, 200],
567          backgroundColor: Color.Gray,
568          blurStyle: BlurStyle.Thick,
569          showClose: true,
570          title: { title: "title", subtitle: "subtitle" },
571          keyboardAvoidMode: SheetKeyboardAvoidMode.RESIZE_ONLY
572        })
573    }
574    .justifyContent(FlexAlign.Start)
575    .width('100%')
576    .height('100%')
577  }
578}
579```
580