@page "/components/touch-ripple"

<PageTitle>TouchRipple — Lumeo</PageTitle>

<PageHeader Title="TouchRipple" Description="A Material Design-style radial ripple that emanates from the exact pointer-down position to give tactile feedback on any tappable element." />

<Alert Variant="Alert.AlertVariant.Default" Class="mt-6"
      Title="TouchRipple vs Button's built-in ripple"
      Description="Button already animates a click ripple via its built-in press-feedback system — don't double-wrap a Button. TouchRipple is a low-level wrapper for any clickable element that doesn't already ripple: a Card, Avatar, a custom div, a list row, or an icon. The canonical use case is a tappable list row — see the demo below." />

<div class="mt-10 space-y-3">
    <Heading Id="when-to-use" Level="2" Class="scroll-mt-20">When to Use</Heading>
    <ul class="list-disc list-inside space-y-1 text-muted-foreground text-sm">
        <li>Cards, list rows, or custom divs that need touch feedback but aren't Buttons</li>
        <li>Mobile-first interfaces where the default browser tap highlight looks inconsistent</li>
        <li>Interactive tiles, gallery items, and menu entries that want a polished feel</li>
        <li>Replacing CSS <code class="font-mono text-xs bg-muted px-1 py-0.5 rounded">:active</code> states with a more expressive animation</li>
        <li>Wrapping any element to add tap feedback without changing its markup or styling</li>
    </ul>
</div>

<Stack Gap="8" Class="mt-8">
    <ComponentDemo Title="Basic Ripple on a Button" Code="@_basicCode">
        <TouchRipple Class="inline-block rounded-md">
            <Button>Tap me</Button>
        </TouchRipple>
    </ComponentDemo>

    <ComponentDemo Title="Custom Color" Code="@_colorCode">
        <Stack Direction="Stack.StackDirection.Horizontal" Gap="4" Wrap="true">
            <TouchRipple Color="#3b82f6" Class="inline-block rounded-md">
                <Button Variant="Button.ButtonVariant.Secondary">Blue ripple</Button>
            </TouchRipple>
            <TouchRipple Color="#ef4444" Class="inline-block rounded-md">
                <Button Variant="Button.ButtonVariant.Secondary">Red ripple</Button>
            </TouchRipple>
            <TouchRipple Color="#22c55e" Class="inline-block rounded-md">
                <Button Variant="Button.ButtonVariant.Secondary">Green ripple</Button>
            </TouchRipple>
        </Stack>
    </ComponentDemo>

    <ComponentDemo Title="Custom Opacity and Duration" Code="@_opacityCode">
        <Stack Direction="Stack.StackDirection.Horizontal" Gap="4" Wrap="true">
            <TouchRipple Opacity="0.5" DurationMs="300" Class="inline-block rounded-md">
                <Button Variant="Button.ButtonVariant.Outline">High opacity · Fast (300 ms)</Button>
            </TouchRipple>
            <TouchRipple Opacity="0.1" DurationMs="900" Class="inline-block rounded-md">
                <Button Variant="Button.ButtonVariant.Outline">Low opacity · Slow (900 ms)</Button>
            </TouchRipple>
        </Stack>
    </ComponentDemo>

    <ComponentDemo Title="Ripple on a Card" Code="@_cardCode">
        <TouchRipple Class="block rounded-xl w-full max-w-sm cursor-pointer">
            <Card Class="p-5">
                <Stack Gap="1">
                    <Lumeo.Text Class="font-medium">Interactive card</Lumeo.Text>
                    <Lumeo.Text Size="sm" Color="muted">Tap anywhere on this card to see the ripple originate from your touch point.</Lumeo.Text>
                </Stack>
            </Card>
        </TouchRipple>
    </ComponentDemo>

    <ComponentDemo Title="List row (canonical mobile pattern)" Description="The most common TouchRipple use case: a tappable list row that isn't a Button. Each row is a custom div, so it gets no built-in ripple — TouchRipple adds it." Code="@_listRowCode">
        <Card Class="w-full max-w-sm divide-y divide-border/40 overflow-hidden">
            @foreach (var item in _listItems)
            {
                var captured = item;
                <TouchRipple Class="block w-full cursor-pointer" @key="captured">
                    <div class="flex items-center gap-3 px-4 py-3" @onclick="@(() => _selectedItem = captured)">
                        <div class="h-9 w-9 rounded-full bg-primary/10 flex items-center justify-center shrink-0">
                            <Blazicon Svg="Lucide.User" class="h-4 w-4 text-primary" />
                        </div>
                        <Stack Gap="0.5" Class="flex-1 min-w-0">
                            <Lumeo.Text Size="sm" Class="font-medium truncate">@captured</Lumeo.Text>
                            <Lumeo.Text Size="xs" Color="muted">Tap to select</Lumeo.Text>
                        </Stack>
                        @if (_selectedItem == captured)
                        {
                            <Blazicon Svg="Lucide.Check" class="h-4 w-4 text-primary shrink-0" />
                        }
                    </div>
                </TouchRipple>
            }
        </Card>
        @if (_selectedItem is not null)
        {
            <Lumeo.Text Size="sm" Color="muted" Class="mt-3">Selected: @_selectedItem</Lumeo.Text>
        }
    </ComponentDemo>
</Stack>

<!-- API Reference -->
<Stack Gap="6" Class="mt-12">
    <Heading Level="2">API Reference</Heading>
    <Stack Gap="8" Class="mt-8">
        <Stack Gap="3">
            <Heading Level="3">TouchRipple</Heading>
            <Stack Class="rounded-lg border border-border/40 overflow-x-auto">
                <table class="w-full min-w-[600px] text-sm">
                    <thead>
                        <tr class="border-b border-border/40 bg-muted/40">
                            <th class="text-left p-3 font-medium text-foreground">Property</th>
                            <th class="text-left p-3 font-medium text-foreground">Type</th>
                            <th class="text-left p-3 font-medium text-foreground">Default</th>
                            <th class="text-left p-3 font-medium text-foreground">Description</th>
                        </tr>
                    </thead>
                    <tbody class="divide-y divide-border/40">
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">ChildContent</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">RenderFragment?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">—</td>
                            <td class="p-3 text-muted-foreground">The element(s) to wrap with ripple feedback. Must have a definite size for the ripple to be visible.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Color</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">string</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">"currentColor"</td>
                            <td class="p-3 text-muted-foreground">CSS color value for the ripple. Accepts any valid CSS color (hex, hsl, named color, currentColor).</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Opacity</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">double</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">0.25</td>
                            <td class="p-3 text-muted-foreground">Peak opacity of the ripple wave. Use lower values (0.1–0.15) on light backgrounds and higher values (0.3–0.5) for stronger emphasis.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">DurationMs</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">int</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">500</td>
                            <td class="p-3 text-muted-foreground">Duration of the ripple animation in milliseconds. Controls both expand and fade timing.</td>
                        </tr>
                        <tr>
                            <td class="p-3 font-mono text-xs text-primary">Class</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">string?</td>
                            <td class="p-3 font-mono text-xs text-muted-foreground">null</td>
                            <td class="p-3 text-muted-foreground">Additional CSS classes for the ripple container. Use to set display (inline-block, block) and border-radius to match the child.</td>
                        </tr>
                    </tbody>
                </table>
            </Stack>
        </Stack>
    </Stack>
</Stack>

<div class="mt-12">
    <Heading Id="related" Level="2" Class="scroll-mt-20">Related Components</Heading>
    <ul class="mt-4 space-y-2 text-sm">
        <li><a href="/components/button" class="text-primary hover:underline">Button</a> — Primary interactive element that pairs naturally with TouchRipple</li>
        <li><a href="/components/card" class="text-primary hover:underline">Card</a> — Content container that can be made tappable with TouchRipple</li>
        <li><a href="/components/swipe-actions" class="text-primary hover:underline">SwipeActions</a> — Swipeable row with action buttons that can also use TouchRipple</li>
    </ul>
</div>

@code {
    private string[] _listItems = ["Alice Johnson", "Bob Martinez", "Carol Williams"];
    private string? _selectedItem;

    private string _basicCode = @"<TouchRipple Class=""inline-block rounded-md"">
    <Button>Tap me</Button>
</TouchRipple>";

    private string _colorCode = @"<TouchRipple Color=""#3b82f6"" Class=""inline-block rounded-md"">
    <Button Variant=""ButtonVariant.Secondary"">Blue ripple</Button>
</TouchRipple>

<TouchRipple Color=""#ef4444"" Class=""inline-block rounded-md"">
    <Button Variant=""ButtonVariant.Secondary"">Red ripple</Button>
</TouchRipple>";

    private string _opacityCode = @"<!-- High opacity, fast -->
<TouchRipple Opacity=""0.5"" DurationMs=""300"" Class=""inline-block rounded-md"">
    <Button Variant=""ButtonVariant.Outline"">Fast (300 ms)</Button>
</TouchRipple>

<!-- Low opacity, slow -->
<TouchRipple Opacity=""0.1"" DurationMs=""900"" Class=""inline-block rounded-md"">
    <Button Variant=""ButtonVariant.Outline"">Slow (900 ms)</Button>
</TouchRipple>";

    private string _cardCode = @"<TouchRipple Class=""block rounded-xl w-full max-w-sm cursor-pointer"">
    <Card Class=""p-5"">
        <Text Class=""font-medium"">Interactive card</Text>
        <Text Size=""sm"" Color=""muted"">Tap anywhere to see the ripple.</Text>
    </Card>
</TouchRipple>";

    private string _listRowCode = @"<Card Class=""divide-y divide-border/40 overflow-hidden"">
    @foreach (var item in _listItems)
    {
        var captured = item;
        <TouchRipple Class=""block w-full cursor-pointer"" @key=""captured"">
            <div class=""flex items-center gap-3 px-4 py-3"" @onclick=""@(() => _selectedItem = captured)"">
                <div class=""h-9 w-9 rounded-full bg-primary/10 flex items-center justify-center shrink-0"">
                    <Blazicon Svg=""Lucide.User"" class=""h-4 w-4 text-primary"" />
                </div>
                <Text Size=""sm"" Class=""font-medium truncate"">@captured</Text>
            </div>
        </TouchRipple>
    }
</Card>

@code {
    private string[] _listItems = [""Alice Johnson"", ""Bob Martinez"", ""Carol Williams""];
    private string? _selectedItem;
}";
}
