true-perfect-code
Version: 1.1.69

P11DrawerNative Component

The P11DrawerNative is a lightweight, pure HTML/CSS-based drawer (or offcanvas) component that operates without relying on Bootstrap JavaScript. It provides a highly accessible, customizable slide-out panel, complete with features like overlays, focus trapping, and scroll prevention.
Note: This component manages its behavior (like focus trapping and scroll prevention) using internal JavaScript interop to ensure full accessibility and a smooth user experience, even without external frameworks.


P11DrawerNative Component Examples

These examples demonstrate various configurations and functionalities of the P11DrawerNative component, showcasing its flexibility for different use cases.

Drawer from Left (Default, with Title & Close Button and Size)

This is a drawer that slides in from the left. It has a title and a built-in close button. The background does not scroll, and focus is trapped within the drawer. Press ESC to close.




Current Status (Left): Closed

Implementation

<h4 class="mb-3">Drawer from Left (Default, with Title & Close Button)</h4>
<p>This is a drawer that slides in from the left. It has a title and a built-in close button. The background does not scroll, and focus is trapped within the drawer. Press ESC to close.</p>
<button class="btn btn-primary" @onclick="() => isDrawerLeftOpen = true">Open Left Drawer</button>
<P11DrawerNative @bind-IsOpen="isDrawerLeftOpen"
                 Position="DrawerPosition.Left"
                 HasOverlay="true"
                 Title="Main Left Drawer"
                 ShowCloseButton="true"
                 PreventScroll="true"
                 EnableFocusTrap="true"
                 CloseOnOutsideClick="true"
                 AdditionalAttributes="@(new Dictionary<string, object> { { "id", "drawer-left-main" } })">
    <div style="padding: 20px;">
        <p>This is a drawer that slides in from the left. It has a title and a built-in close button.</p>
        <p>The background does not scroll, and focus is trapped within the drawer. Press ESC to close.</p>
        <p>Some random content to test scrolling if the content is too long:</p>
        @for (int i = 0; i < 20; i++)
        {
            <p>Line @(i + 1) in the left drawer.</p>
        }
    </div>
</P11DrawerNative>
<p>Current Status (Left): @(isDrawerLeftOpen ? "Open" : "Closed")</p>
@code {
    private bool isDrawerLeftOpen = false;
}


Drawer from Right (No Overlay, No Outside Close)

This drawer slides in from the right and has **no** overlay. Clicking outside it will **not** close it. Use the integrated close button or the ESC key.

Current Status (Right): Closed

Implementation

<h4 class="mb-3">Drawer from Right (No Overlay, No Outside Close)</h4>
<p>This drawer slides in from the right and has **no** overlay. Clicking outside it will **not** close it. Use the integrated close button or the ESC key.</p>
<button class="btn btn-info" @onclick="() => isDrawerRightOpen = true">Open Right Drawer (no overlay, no outside close)</button>
<P11DrawerNative @bind-IsOpen="isDrawerRightOpen"
                 Position="DrawerPosition.Right"
                 HasOverlay="false"
                 Title="Right Info Drawer"
                 ShowCloseButton="true"
                 CloseOnOutsideClick="false"
                 AdditionalAttributes="@(new Dictionary<string, object> { { "id", "drawer-right-no-overlay" } })">
    <div style="padding: 20px;">
        <p>This drawer slides in from the right and has **no** overlay. Clicking outside it will **not** close it.</p>
        <p>Use the integrated close button or the ESC key.</p>
        <p>Some random content:</p>
        <ul>
            <li>Item 1</li>
            <li>Item 2</li>
            <li>Item 3</li>
        </ul>
        <button class="btn btn-warning" @onclick="() => isDrawerRightOpen = false">Internal Close Button (for demo only)</button>
    </div>
</P11DrawerNative>
<p>Current Status (Right): @(isDrawerRightOpen ? "Open" : "Closed")</p>
@code {
    private bool isDrawerRightOpen = false;
}


Drawer from Top (Manual Close)

This drawer slides in from the top. The background **can** scroll.

Current Status (Top): Closed

Implementation

<h4 class="mb-3">Drawer from Top (Manual Close)</h4>
<p>This drawer slides in from the top. The background **can** scroll.</p>
<button class="btn btn-warning" @onclick="() => isDrawerTopOpen = true">Open Top Drawer</button>
<P11DrawerNative @bind-IsOpen="isDrawerTopOpen"
                 Position="DrawerPosition.Top"
                 Title="Top Input Drawer"
                 ShowCloseButton="true"
                 PreventScroll="false"
                 AdditionalAttributes="@(new Dictionary<string, object> { { "id", "drawer-top-input" } })">
    <div style="padding: 20px;">
        <p>This drawer slides in from the top. The background **can** scroll.</p>
        <input type="text" class="form-control mb-2" placeholder="Text field in drawer" />
        <textarea class="form-control" rows="3" placeholder="More text"></textarea>
        <button class="btn btn-secondary mt-3" @onclick="() => isDrawerTopOpen = false">Close via internal button</button>
    </div>
</P11DrawerNative>
<p>Current Status (Top): @(isDrawerTopOpen ? "Open" : "Closed")</p>
@code {
    private bool isDrawerTopOpen = false;
}


Drawer from Bottom (No Title, with AriaLabel)

This drawer slides in from the bottom. It has no visible Title parameter, but an AriaLabel for screen readers.

Current Status (Bottom): Closed

Implementation

<h4 class="mb-3">Drawer from Bottom (No Title, with AriaLabel)</h4>
<p>This drawer slides in from the bottom. It has no visible <code>Title</code> parameter, but an <code>AriaLabel</code> for screen readers.</p>
<button class="btn btn-danger" @onclick="() => isDrawerBottomOpen = true">Open Bottom Drawer</button>
<P11DrawerNative @bind-IsOpen="isDrawerBottomOpen"
                 Position="DrawerPosition.Bottom"
                 AriaLabel="Footnotes and Imprint"
                 ShowCloseButton="true"
                 AdditionalAttributes="@(new Dictionary<string, object> { { "id", "drawer-bottom-footer" } })">
    <div style="padding: 20px;">
        <h5>Important Information</h5>
        <p>This drawer has no visible <code>Title</code> parameter, but an <code>AriaLabel</code> for screen readers.</p>
        <p>Imprint | Privacy Policy | Contact</p>
        <button class="btn btn-outline-danger" @onclick="() => isDrawerBottomOpen = false">Close</button>
    </div>
</P11DrawerNative>
<p>Current Status (Bottom): @(isDrawerBottomOpen ? "Open" : "Closed")</p>
@code {
    private bool isDrawerBottomOpen = false;
}


Drawer with Overlay Click Handler & No Development Errors

This drawer closes when the overlay is clicked (in addition to the internal close button). ShowDevelopmentErrors is set to false here.

Overlay Click Message: No overlay click yet.

Current Status (Overlay Test): Closed

Implementation

<h4 class="mb-3">Drawer with Overlay Click Handler & No Development Errors</h4>
<p>This drawer closes when the overlay is clicked (in addition to the internal close button). <code>ShowDevelopmentErrors</code> is set to <code>false</code> here.</p>
<button class="btn btn-success" @onclick="() => isDrawerOverlayTestOpen = true">Open Drawer with Overlay Handler</button>
<P11DrawerNative @bind-IsOpen="isDrawerOverlayTestOpen"
                 Position="DrawerPosition.Left"
                 OnOverlayClick="HandleOverlayTestClick"
                 Title="Overlay Click Test"
                 ShowCloseButton="true"
                 ShowDevelopmentErrors="false"
                 AdditionalAttributes="@(new Dictionary<string, object> { { "id", "drawer-overlay-test" } })">
    <div style="padding: 20px;">
        <p>Click on the overlay to close this drawer and display a message.</p>
        <button class="btn btn-secondary" @onclick="() => isDrawerOverlayTestOpen = false">Close</button>
    </div>
</P11DrawerNative>
<p>Overlay Click Message: @overlayClickMessage</p>
<p>Current Status (Overlay Test): @(isDrawerOverlayTestOpen ? "Open" : "Closed")</p>
@code {
    private bool isDrawerOverlayTestOpen = false;
    private string overlayClickMessage = "No overlay click yet.";

    private void HandleOverlayTestClick()
    {
        overlayClickMessage = $"Overlay clicked at {DateTime.Now:HH:mm:ss}";
    }
}


Drawer that should trigger an Accessibility Warning

This drawer has no Title, AriaLabel, or AriaLabelledby, and ShowDevelopmentErrors is true (default). When opened, a development warning should be displayed on the page.

Current Status (Accessibility Warning): Closed



Fullscreen Drawer Demo: This drawer is configured with IsFullScreen="true", causing it to cover the entire viewport, regardless of its Position parameter. The drawer will slide in from the top as specified by Position="DrawerPosition.Top".

Current Status (Fullscreen Demo): Closed

Implementation

<h4 class="mb-3">Drawer that should trigger an Accessibility Warning</h4>
<p>This drawer has no Title, AriaLabel, or AriaLabelledby, and <code>ShowDevelopmentErrors</code> is <code>true</code> (default). When opened, a development warning should be displayed on the page.</p>
<button class="btn btn-danger" @onclick="() => isDrawerAccessibilityWarningOpen = true">Open Drawer with Warning</button>
<P11DrawerNative @bind-IsOpen="isDrawerAccessibilityWarningOpen"
                 Position="DrawerPosition.Left"
                 HasOverlay="true"
                 ShowCloseButton="true"
                 ShowDevelopmentErrors="true"
                 AdditionalAttributes="@(new Dictionary<string, object> { { "id", "drawer-accessibility-warning" } })">
    <div style="padding: 20px;">
        <p>This is a drawer that should trigger an accessibility warning. Please look at the page.</p>
        <button class="btn btn-secondary" @onclick="() => isDrawerAccessibilityWarningOpen = false">Close</button>
    </div>
</P11DrawerNative>
<p>Current Status (Accessibility Warning): @(isDrawerAccessibilityWarningOpen ? "Open" : "Closed")</p>

<br />
<br />

<p>
    Fullscreen Drawer Demo: This drawer is configured with <code>IsFullScreen="true"</code>, causing it to cover the entire viewport, regardless of its <code>Position</code> parameter. The drawer will slide in from the top as specified by <code>Position="DrawerPosition.Top"</code>.
</p>
<button class="btn btn-primary" @onclick="() => isDrawerFullscreenOpen = true">Open Fullscreen Drawer</button>
<P11DrawerNative @bind-IsOpen="isDrawerFullscreenOpen"
                 Position="DrawerPosition.Top"
                 IsFullScreen="true"
                 Title="Fullscreen Drawer"
                 ShowCloseButton="false"
                 AdditionalAttributes="@(new Dictionary<string, object> { { "id", "drawer-fullscreen" } })">
    <div style="padding: 20px;">
        <p>This drawer is in fullscreen mode. Note how it covers the entire screen, even though its <code>Position</code> is set to `Top`.</p>
        <button class="btn btn-secondary" @onclick="() => isDrawerFullscreenOpen = false">Close</button>
    </div>
</P11DrawerNative>
<p>Current Status (Fullscreen Demo): @(isDrawerFullscreenOpen ? "Open" : "Closed")</p>
@code {
    private bool isDrawerAccessibilityWarningOpen = false;
    private bool isDrawerFullscreenOpen = false;
}


Component API

Parameter Type Default Description
ChildContent RenderFragment? null Gets or sets the content to be rendered inside the drawer.
IsOpen bool false Gets or sets a boolean indicating whether the drawer is currently open and visible. Use @bind-IsOpen for two-way data binding.
Position DrawerPosition DrawerPosition.Left Gets or sets the position from which the drawer slides into view. Defaults to DrawerPosition.Left.
IsFullScreen bool false Gets or sets a boolean indicating whether the drawer should take up the full screen. If true, this overrides the default width/height set by the Position parameter.
HasOverlay bool true Gets or sets a boolean indicating whether a semi-transparent overlay (backdrop) should be displayed when the drawer is open, to visually block the background content.
Title string? null Gets or sets the title text for the drawer. If provided, this will be rendered as an <h5> element inside the drawer and will automatically set the aria-labelledby attribute for accessibility.
AriaLabel string? null Gets or sets the value for the aria-label attribute on the drawer's main element. This provides an accessible name for screen readers when no Title or AriaLabelledby is provided.
AriaLabelledby string? null Gets or sets the value for the aria-labelledby attribute on the drawer's main element. This should be the ID of an element that labels the drawer. If Title is provided, this parameter is overridden.
PreventScroll bool true Gets or sets a boolean indicating whether to prevent scrolling of the background content (body element) when the drawer is open. Requires JavaScript interop.
EnableFocusTrap bool true Gets or sets a boolean indicating whether focus should be trapped inside the drawer when it is open, preventing tabbing to elements outside the drawer. Requires JavaScript interop.
CloseOnOutsideClick bool true Gets or sets a boolean indicating whether the drawer should close when a click occurs outside the drawer itself (but not on the overlay if HasOverlay is false). Requires JavaScript interop.
ShowCloseButton bool false Gets or sets a boolean indicating whether a close button (X icon) should be displayed in the top-right corner of the drawer.
CustomClass string? null Gets or sets an additional CSS class to be applied to the main drawer container.
CustomSize int 0 Sets the width of the drawer.
ShowDevelopmentErrors bool true Gets or sets a value indicating whether development-time configuration errors should be displayed. Defaults to true. Set to false for production environments.
AdditionalAttributes Dictionary<string, object>? null Captures additional HTML attributes passed to the component that are not explicitly defined as parameters. These attributes will be applied to the main drawer container element.
Events
IsOpenChanged EventCallback<bool> - Event callback that is invoked when the IsOpen property changes. Required for @bind-IsOpen functionality.
OnOverlayClick EventCallback - Event callback that is invoked when the overlay (backdrop) is clicked. This typically triggers the closing of the drawer.
An unhandled error has occurred. Reload 🗙