Taiga UI 5.0 is out!

SheetDialog ADDON-MOBILE

Examples API Setup GitHub

On this page

See also

Dialog, BottomSheet
A mobile draggable sheet dialog

String

    
      
    
    
      <button
    tuiButton
    type="button"
    (click)="onClick()"
>
    Show
</button>

    

Basic

    
      
    
    
      <button
    tuiButton
    type="button"
    (click)="open = true"
>
    Show
</button>
<ng-template
    let-observer
    [tuiSheetDialogOptions]="options"
    [(tuiSheetDialog)]="open"
>
    <div>
        <a
            appearance="secondary"
            href="mailto:alexander@inkin.ru"
            iconStart="@tui.mail"
            size="m"
            tuiIconButton
            class="tui-space_right-2"
        >
            Email
        </a>
        <a
            appearance="secondary"
            href="https://t.me/waterplea"
            iconStart="@tui.phone-forwarded"
            size="m"
            tuiIconButton
            class="tui-space_right-2"
        >
            Telegram
        </a>
        <a
            appearance="secondary"
            href="https://waterplea.bandcamp.com/"
            iconStart="@tui.music"
            size="m"
            tuiIconButton
        >
            Music
        </a>
    </div>
    <p>Passionate Angular dev, musician and OSS author.</p>
    <footer
        tuiFloatingContainer
        class="footer"
    >
        <button
            size="m"
            tuiButton
            type="button"
            (click)="observer.complete()"
        >
            Give a raise
        </button>
        <button
            appearance="secondary"
            size="m"
            tuiButton
            type="button"
            (click)="observer.complete()"
        >
            Fire
        </button>
    </footer>
</ng-template>

    

Advanced

    
      
    
    
      <button
    tuiButton
    type="button"
    (click)="open = true"
>
    Show/Hide
</button>
<ng-template #label>
    <label tuiTitle>
        <span tuiSubtitle>Monty Python</span>
        <b>And the Holy Grail</b>
    </label>
</ng-template>
<ng-template
    [tuiSheetDialogOptions]="{stops: ['5.75rem', '13.875rem']}"
    [(tuiSheetDialog)]="open"
>
    <header tuiHeader="body-m">
        <hgroup tuiTitle>
            <p tuiSubtitle>Monty Python</p>
            <h2>And the Holy Grail</h2>
        </hgroup>
    </header>
    <p class="buttons">
        <button
            appearance="secondary"
            size="m"
            tuiButton
            type="button"
        >
            Buy {{ 12.99 | tuiAmount: 'USD' }}
        </button>
        <button
            appearance="secondary"
            size="m"
            tuiButton
            type="button"
        >
            Rent {{ 4.99 | tuiAmount: 'USD' }}
        </button>
    </p>
    <div>
        <h3>Cast:</h3>
        <p>John Cleese</p>
        <p>Eric Idle</p>
        <p>Michael Palin</p>
        <p>Graham Chapman</p>
        <p>Terry Gilliam</p>
        <p>Terry Jones</p>
        <p>Carol Cleveland</p>
        <hr />
        <h3>Directed by:</h3>
        <p>Terry Gilliam</p>
        <p>Terry Jones</p>
        <hr />
        <h3>Produced by:</h3>
        <p>Mark Forstater</p>
        <p>Michael White</p>
        <hr />
        <h3>Written by:</h3>
        <p>John Cleese</p>
        <p>Eric Idle</p>
        <p>Michael Palin</p>
        <p>Graham Chapman</p>
        <p>Terry Gilliam</p>
        <p>Terry Jones</p>
        <hr />
        <h3>Budget:</h3>
        <p>{{ 400000 | tuiAmount: 'USD' }}</p>
        <hr />
        <h3>Box office:</h3>
        <p>{{ 5000000 | tuiAmount: 'USD' }}</p>
        <hr />
        <h3>Release date</h3>
        <p>April 3, 1975</p>
        <hr />
        <h3>Running time</h3>
        <p>92 minutes</p>
        <footer class="footer">© EMI Films</footer>
        <div
            tuiFloatingContainer
            class="floating"
        >
            <button
                size="m"
                tuiButton
                type="button"
            >
                Add to Watch List
            </button>
        </div>
    </div>
</ng-template>

    
    
      .buttons {
    display: flex;
    margin: 0 0 1rem;
    gap: 0.5rem;

    & button {
        flex: 1;
    }
}

.footer {
    padding: 1rem 0 1.25rem;
    border-image: conic-gradient(var(--tui-background-base-alt) 0 0) fill 0/0/0 100vh 100vh;
}

.floating {
    margin-block-start: -1rem;
    padding-block-start: 1rem;
}

    

Sticky elements

    
      
    
    
      <button
    tuiButton
    type="button"
    (click)="toggle(true)"
>
    Show/Hide
</button>

<ng-template
    [tuiSheetDialog]="open"
    [tuiSheetDialogOptions]="{stops: ['29rem'], offset: offset, appearance: 'fullscreen'}"
    (tuiSheetDialogChange)="toggle($event)"
>
    <header class="header">
        <tui-textfield iconStart="@tui.search">
            <input
                tuiInput
                [formControl]="search"
            />
            <label tuiLabel>Find user</label>
        </tui-textfield>
    </header>
    <div class="container">
        @for (user of users$ | async; track user) {
            <button
                type="button"
                class="item"
                (click)="toggle(false)"
            >
                <div
                    size="s"
                    [style.background]="user | tuiAutoColor"
                    [tuiAvatar]="user | tuiInitials"
                ></div>
                {{ user }}
            </button>
        }
    </div>
    <footer tuiFloatingContainer>
        <button
            tuiButton
            type="button"
            (click)="toggle(false)"
        >
            Invite more users
        </button>
        <span class="legal">Opens a separate app</span>
    </footer>
</ng-template>

    
    
      @import '@taiga-ui/styles/utils.less';

.header {
    padding-block: 0.25rem 1rem;
}

.container {
    flex-grow: 1;
}

.item {
    all: unset;
    display: flex;
    block-size: 3rem;
    align-items: center;
    gap: 1rem;
}

.legal {
    .tui-line-clamp();

    margin-block-start: 0.5rem;
    min-block-size: 2rem;
}

    

Responsive

    
      
    
    
      <button
    tuiButton
    type="button"
    (click)="open = true"
>
    Show
</button>
<ng-template
    let-observer
    [tuiResponsiveDialogOptions]="options"
    [(tuiResponsiveDialog)]="open"
>
    <div>
        This dialog would show up as regular
        <a
            tuiLink
            [routerLink]="routes.Dialog"
        >
            Dialog
        </a>
        on desktop and as a
        <code>SheetDialog</code>
        on a mobile device.
    </div>
    <footer>
        <button
            appearance="secondary"
            size="m"
            tuiButton
            type="button"
            (click)="observer.complete()"
        >
            Glad to know that
        </button>
        <button
            size="m"
            tuiButton
            type="button"
            (click)="observer.complete()"
        >
            Sure
        </button>
    </footer>
</ng-template>

    

AppBar

When mobile styles are enabled you can use input[type='search'][tuiSearch] to imitate iOS native input

    
      
    
    
      <div tuiNotification>
    When mobile styles are enabled you can use
    <code style="white-space: nowrap">input[type='search'][tuiSearch]</code>
    to imitate iOS native input
</div>
<p>
    <button
        tuiButton
        type="button"
        (click)="open.set(true)"
    >
        Show
    </button>
</p>
<ng-template
    [tuiSheetDialogOptions]="{appearance: 'fullscreen', bar: false}"
    [(tuiSheetDialog)]="open"
>
    <header>
        <tui-app-bar>
            <button
                tuiButton
                tuiSlot="start"
                type="button"
                (click)="open.set(false)"
            >
                Close
            </button>
            Search contacts
        </tui-app-bar>
        <input
            placeholder="Search contacts"
            tuiSearch
            type="search"
            class="input"
            [(ngModel)]="search"
        />
    </header>
    <div class="favorites">
        @for (item of items | slice: 0 : 6; track item) {
            <tui-avatar-labeled [label]="item.name">
                <div tuiAvatar="@tui.user">
                    <img
                        alt=""
                        [src]="item.avatar"
                    />
                </div>
            </tui-avatar-labeled>
        }
    </div>
    <div class="items">
        @for (item of items | tuiFilter: filter : search; track item) {
            <button
                tuiCell
                type="button"
                class="cell"
                (click)="open.set(false)"
            >
                <div tuiAvatar="@tui.user">
                    <img
                        alt=""
                        [src]="item.avatar"
                    />
                </div>
                <span tuiTitle>
                    <span tuiFade>{{ item.name }}</span>
                    <span tuiSubtitle>{{ item.email }}</span>
                </span>
            </button>
        }
    </div>
    <footer tuiFloatingContainer>
        <button
            tuiButton
            type="button"
            class="button"
            (click)="open.set(false)"
        >
            Add contact
        </button>
    </footer>
</ng-template>

    
    
      @import '@taiga-ui/styles/utils.less';

.input {
    .tui-prevent-ios-scroll();

    inline-size: 100%;
    margin-block-start: 0.75rem;
}

.favorites {
    .scrollbar-hidden();

    display: flex;
    gap: 0.75rem;
    margin: 1rem -1rem;
    padding: 0 0.5rem;
    overflow: auto;
}

.items {
    min-block-size: calc(100 * var(--tui-viewport-vh) - var(--tui-offset) - 19.5rem);
}

.cell {
    inline-size: 100%;
    margin: 0 -1rem;
    white-space: nowrap;
    overflow: hidden;
    border-radius: 0;
}

.button {
    .transition(inset-block-end);
}

    

Fullscreen

    
      
    
    
      <button
    tuiButton
    type="button"
    (click)="open = true"
>
    Show
</button>
<ng-template
    let-observer
    [tuiSheetDialogOptions]="options"
    [(tuiSheetDialog)]="open"
>
    <span>
        <a
            appearance="secondary"
            href="mailto:alexander@inkin.ru"
            iconStart="@tui.mail"
            size="m"
            tuiIconButton
            class="tui-space_right-2"
        >
            Email
        </a>
        <a
            appearance="secondary"
            href="https://t.me/waterplea"
            iconStart="@tui.phone-forwarded"
            size="m"
            tuiIconButton
            class="tui-space_right-2"
        >
            Telegram
        </a>
        <a
            appearance="secondary"
            href="https://waterplea.bandcamp.com/"
            iconStart="@tui.music"
            size="m"
            tuiIconButton
        >
            Music
        </a>
    </span>
    <p [style.flex-grow]="1">Passionate Angular dev, musician and OSS author.</p>
    <footer tuiFloatingContainer>
        <button
            size="m"
            tuiButton
            type="button"
            (click)="observer.complete()"
        >
            Give a raise
        </button>
        <button
            appearance="secondary"
            size="m"
            tuiButton
            type="button"
            (click)="observer.complete()"
        >
            Fire
        </button>
    </footer>
</ng-template>