true-perfect-code
Version: 1.2.65

P11Category Component

The P11Category is a high-end content slider designed for emotional hero sections. It supports advanced cinematic effects like Ken Burns, Parallax, and Blur Reveal. It is fully responsive, optimized for performance via hardware acceleration, and includes an optional glassmorphism progress indicator.

P11 UI Category - Auto-Loop Demo


Implementation

<div class="container mt-5">
    <h2>P11 UI Category - Auto-Loop Demo</h2>

    <P11Category TItem="VisualShowcaseModel"
                 Items="_visualShowcaseItems"
                 AriaLabel="Test"
                 Interval="4000"
                 VisibleSlotsSm="1"
                 VisibleSlotsMd="2"
                 VisibleSlotsLg="4"
                 Gap="3"
                 Animation="P11AnimationType.BlurReveal"
                 IsFullScreen="false"
                 Height="550px">

        <BackgroundTemplate Context="item">
            <div class="h-100 w-100"
                 style="background: url('@item.MediaUrl');
                background-size: cover;
                background-position: center;">
            </div>
        </BackgroundTemplate>

        <OverlayTemplate Context="item">
            @* Layer 3: Fokus auf die produktspezifischen Informationen *@
            <div class="h-100 w-100 d-flex flex-column justify-content-end p-3 text-white">

                @* Container für die untere Zeile: Infos links, Button rechts *@
                <div class="d-flex justify-content-between align-items-end">

                    @* Linke Seite: Text-Informationen *@
                    <div class="p11-item-info">
                        <h6 class="fw-bold mb-0">@item.SubHeading</h6>

                        @if (item.PriceTag > 0)
                        {
                            <p class="small mb-0 opacity-75">Ab @item.PriceTag.ToString("N2") €</p>
                        }
                    </div>

                    @* Rechte Seite: More Info Button *@
                    <button class="btn btn-sm p11-btn-more-info"
                            @onclick:stopPropagation="true"
                            @onclick="@(() => {
                                _visualShowcaseItems.Remove(item);
                                //VisualShowcaseModel itemAdd = new VisualShowcaseModel 
                                //{ 
                                //    Category = "TEST", 
                                //    Symbol = "🥾", 
                                //    SubHeading = "Test Pack", 
                                //    MediaUrl = "https://picsum.photos/id/11/800/600", 
                                //    PriceTag = 89.00, 
                                //    AriaLabel = "Test category item" 
                                //};
                                _visualShowcaseItems.Add(item);
                            })"
                            style="background: rgba(255, 255, 255, 0.2);
                               border: 1px solid rgba(255, 255, 255, 0.4);
                               color: white;
                               backdrop-filter: blur(4px);
                               font-size: 0.75rem;
                               padding: 0.4rem 0.8rem;
                               transition: all 0.2s ease;">
                        DELETE
                    </button>
                </div>
            </div>
        </OverlayTemplate>

    </P11Category>

    <hr />

    <P11Category TItem="PartnerBrand"
                 Items="_partners"
                 Interval="20000"
                 VisibleSlotsLg="5"
                 VisibleSlotsMd="3"
                 VisibleSlotsSm="2"
                 Height="120px"
                 Gap="2"
                 OverlayColor="Black"
                 OverlayOpacity="0.7">

        <BackgroundTemplate Context="partner">
            @* Layer 1: Das Logo, zentriert und skaliert *@
            <div class="h-100 w-100 d-flex align-items-center justify-content-center">
                <img src="@partner.LogoUrl"
                     alt="@partner.Name"
                     class="p11-logo-img" />
            </div>
        </BackgroundTemplate>

        <OverlayTemplate Context="partner">
            @* Layer 3: Der Container dient jetzt nur noch dem Layout (zentrieren).
               'cursor: default' sorgt dafür, dass man nicht denkt, das Bild sei klickbar.
            *@
            <div class="h-100 w-100 d-flex flex-column align-items-center justify-content-center text-center p11-hover-info"
                 style="cursor: default;">

                <small class="fw-bold text-primary mb-1">@partner.Name</small>

                @* Hier findet die Action statt! 
                   Nur der Button hat den Cursor und den Click-Handler.
                *@
                <button class="btn btn-sm btn-outline-primary"
                        style="font-size: 0.6rem; padding: 2px 5px; cursor: pointer;"
                        @onclick="() => OpenImage(partner.MediaUrl)"
                        @onclick:stopPropagation="true">
                    Besuchen
                </button>
            </div>
        </OverlayTemplate>

    </P11Category>

</div>
@code {
    public class VisualShowcaseModel : IP11CarouselEntity
    {
        public string Id { get; set; } = Guid.NewGuid().ToString();
        public string Category { get; set; } = "";
        public string Heading { get; set; } = "";
        public string SubHeading { get; set; } = "";
        public string ThemeColor { get; set; } = "#FFFFFF";
        public string Symbol { get; set; } = "";
        public double PriceTag { get; set; }

        // Interface-Implementierung für P11 Standard
        public string AriaLabel { get; set; } = string.Empty;
        public string MediaUrl { get; set; } = string.Empty;
    }

    private List<VisualShowcaseModel> _visualShowcaseItems = new()
    {
        // 1. Kategorie: Hiking
        new VisualShowcaseModel { Category = "Hiking", Symbol = "🥾", SubHeading = "Pro Boot X1", MediaUrl = "https://picsum.photos/id/10/800/600", PriceTag = 129.00, AriaLabel = "Hiking category item" },
        new VisualShowcaseModel { Category = "Hiking", Symbol = "🥾", SubHeading = "Summit Pack", MediaUrl = "https://picsum.photos/id/11/800/600", PriceTag = 89.00, AriaLabel = "Hiking category item" },

        // 2. Kategorie: Camping
        new VisualShowcaseModel { Category = "Camping", Symbol = "⛺", SubHeading = "NightShelter 3", MediaUrl = "https://picsum.photos/id/103/800/600", PriceTag = 299.00, AriaLabel = "Camping category item" },
        new VisualShowcaseModel { Category = "Camping", Symbol = "⛺", SubHeading = "FireStar Stove", MediaUrl = "https://picsum.photos/id/104/800/600", PriceTag = 45.00, AriaLabel = "Camping category item" },

        // 3. Kategorie: Photo
        new VisualShowcaseModel { Category = "Photo", Symbol = "📷", SubHeading = "Vista Lens 35mm", MediaUrl = "https://picsum.photos/id/250/800/600", PriceTag = 599.00, AriaLabel = "Photography category item" },
        new VisualShowcaseModel { Category = "Photo", Symbol = "📷", SubHeading = "Pro Tripod Alpha", MediaUrl = "https://picsum.photos/id/251/800/600", PriceTag = 120.00, AriaLabel = "Photography category item" },

        // 4. Kategorie: Biking
        new VisualShowcaseModel { Category = "Biking", Symbol = "🚲", SubHeading = "Trail Runner V2", MediaUrl = "https://picsum.photos/id/146/800/600", PriceTag = 1450.00, AriaLabel = "Biking category item" },
        new VisualShowcaseModel { Category = "Biking", Symbol = "⛑️", SubHeading = "Aero Helmet", MediaUrl = "https://picsum.photos/id/147/800/600", PriceTag = 85.00, AriaLabel = "Biking category item" },

        // 5. Kategorie: Winter
        new VisualShowcaseModel { Category = "Winter", Symbol = "🎿", SubHeading = "Powder Carver", MediaUrl = "https://picsum.photos/id/152/800/600", PriceTag = 420.00, AriaLabel = "Winter sports category item" },
        new VisualShowcaseModel { Category = "Winter", Symbol = "🥽", SubHeading = "Thermal Goggles", MediaUrl = "https://picsum.photos/id/153/800/600", PriceTag = 65.00, AriaLabel = "Winter sports category item" },

        // 6. Kategorie: Urban
        new VisualShowcaseModel { Category = "Urban", Symbol = "🧥", SubHeading = "City Slicker Jacket", MediaUrl = "https://picsum.photos/id/158/800/600", PriceTag = 195.00, AriaLabel = "Urban lifestyle category item" },
        new VisualShowcaseModel { Category = "Urban", Symbol = "👟", SubHeading = "Metro Sneakers", MediaUrl = "https://picsum.photos/id/159/800/600", PriceTag = 110.00, AriaLabel = "Urban lifestyle category item" },

        // 7. Kategorie: Water
        new VisualShowcaseModel { Category = "Water", Symbol = "🏄", SubHeading = "BlueWave Board", MediaUrl = "https://picsum.photos/id/164/800/600", PriceTag = 850.00, AriaLabel = "Water sports category item" },
        new VisualShowcaseModel { Category = "Water", Symbol = "🧜", SubHeading = "Pro Wetsuit", MediaUrl = "https://picsum.photos/id/165/800/600", PriceTag = 230.00, AriaLabel = "Water sports category item" }
    };

    public class PartnerBrand : IP11CarouselEntity
    {
        public string Name { get; set; } = string.Empty;
        public string LogoUrl { get; set; } = string.Empty;
        public string Industry { get; set; } = string.Empty;

        // Interface-Implementierung für P11 Standard
        public string AriaLabel => $"Partner Unternehmen: {Name}";
        public string Category => Industry;
        public string MediaUrl { get; set; } = string.Empty;
    }
    private List<PartnerBrand> _partners = new()
    {
        new() { Name = "Google", LogoUrl = "https://picsum.photos/id/1/200/100", Industry = "Software", MediaUrl = "https://google.com" },
        new() { Name = "Microsoft", LogoUrl = "https://picsum.photos/id/2/200/100", Industry = "Software", MediaUrl = "https://microsoft.com" },
        new() { Name = "Apple", LogoUrl = "https://picsum.photos/id/3/200/100", Industry = "Hardware", MediaUrl = "https://apple.com" },
        new() { Name = "Meta", LogoUrl = "https://picsum.photos/id/4/200/100", Industry = "Social Media", MediaUrl = "https://meta.com" },
        new() { Name = "Amazon", LogoUrl = "https://picsum.photos/id/5/200/100", Industry = "E-Commerce", MediaUrl = "https://amazon.com" },
        new() { Name = "Tesla", LogoUrl = "https://picsum.photos/id/6/200/100", Industry = "Automotive", MediaUrl = "https://tesla.com" }
    };

    private async Task OpenImage(string url)
    {
        // Öffnet das Bild in einem neuen Tab (simples Resize/Zoom-Szenario)
        await JSRuntime.InvokeVoidAsync("open", url, "_blank");
    }
}


Component API: P11Category

Parameter Type Default Description
Items IEnumerable<TItem>? null Primary data source. Items must implement IP11CarouselEntity to enable automatic grouping by the Category property.
BackgroundTemplate RenderFragment<TItem>? null Template for Layer 1. Defines the background media (images/videos) for each rotating item.
OverlayTemplate RenderFragment<TItem>? null Template for Layer 2/3. Used for static content like titles or action buttons per category.
Height string "500px" Fixed height when IsFullScreen is false. Supports standard CSS units.
IsFullScreen bool false When enabled, the component fills 100% of the dynamic viewport height (100dvh).
Gap int 0 Spacing between category slots based on Bootstrap scale (0-5). Maps to 'g-{n}'.
VisibleSlotsSm int 1 Visible categories on mobile devices (< 768px).
VisibleSlotsMd int 3 Visible categories on tablets (≥ 768px).
VisibleSlotsLg int 4 Visible categories on desktop screens (≥ 1200px).
Animation P11AnimationType Slide The transition effect for items inside the categories.
Interval int 5000 Duration in milliseconds between automatic slide changes.
AutoCycle bool true If true, items within categories rotate automatically.
IsAsync bool false If enabled, each category slot operates on its own independent timer for an organic look.
GalleryOrder P11GalleryOrder Asc Playback logic for the items: Ascending, Descending or Random.
OverlayColor string "black" Background color for the semi-transparent overlay layer.
OverlayOpacity double 0.0 Opacity of the overlay layer (0.0 = transparent, 1.0 = opaque).
An unhandled error has occurred. Reload 🗙