Files
WRNexusJS/.publish/ui/components/alert.wrn
T
2026-08-01 01:09:58 +05:30

146 lines
4.2 KiB
Plaintext

component Alert {
outputs {
dismiss(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
action(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
}
props {
size: string = "default"
color: string = "info"
variant: string = "soft"
class: string = ""
radius: string = "md"
shadow: string = "sm"
title: string = "Alert"
description: string = ""
items: unknown[] = []
actions: unknown[] = []
showIcon: boolean = false
icon: string = ""
dismissible: boolean = false
dismissLabel: string = "Dismiss alert"
role: string = "alert"
live: string = "polite"
linkLabel: string = ""
linkHref: string = ""
actionLabel: string = ""
actionHref: string = ""
compact: boolean = false
}
state visible: boolean = true
functions {
client function dispatchAlertEvent(sourceEvent, eventName, action, root, customEvent) {
root = sourceEvent.currentTarget.closest("[data-wrn-alert]")
if (!root) {
return
}
customEvent = document.createEvent("CustomEvent")
customEvent.initCustomEvent(eventName, true, false, {
component: "Alert",
title: title,
color: color,
variant: variant,
action: action
})
root.dispatchEvent(customEvent)
}
client function dismissAlert(sourceEvent) {
visible = false
dispatchAlertEvent(sourceEvent, "dismiss", null)
}
client function selectAction(sourceEvent, action) {
dispatchAlertEvent(sourceEvent, "action", action)
}
}
view {
<section
{...attrs}
data-wrn-alert
data-color="{color}"
data-variant="{variant}"
data-radius="{radius}"
data-shadow="{shadow}"
data-show="visible"
aria-hidden="{visible ? 'false' : 'true'}"
role="{role}"
aria-live="{live}"
class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--alert wire-next--alert-{variant} {compact ? 'wire-next--alert-compact' : ''} {class}"
>
{#if showIcon}
<span class="wire-next__alert-icon" aria-hidden="true">
{#if icon}
<span class="{icon}"></span>
{:else if color === "success"}
<span class="icon-[lucide--circle-check]"></span>
{:else if color === "danger"}
<span class="icon-[lucide--circle-x]"></span>
{:else if color === "warning"}
<span class="icon-[lucide--triangle-alert]"></span>
{:else}
<span class="icon-[lucide--info]"></span>
{/if}
</span>
{/if}
<div class="wire-next__alert-body">
{#if title}<strong class="wire-next__alert-title">{title}</strong>{/if}
{#if description}<p>{description}</p>{/if}
{#if items.length > 0}
<ul>
{#each items as item}<li>{item.label || item}</li>{/each}
</ul>
{/if}
{#if actions.length > 0 || actionLabel || linkLabel}
<div class="wire-next__alert-actions">
{#each actions as item}
<a
href="{item.href || '#'}"
data-variant="{item.variant || 'link'}"
@click="selectAction(event, item)"
>{item.label}</a>
{/each}
{#if actionLabel}
<a
href="{actionHref || '#'}"
data-variant="action"
@click="selectAction(event, { label: actionLabel, href: actionHref })"
>{actionLabel}</a>
{/if}
{#if linkLabel}
<a
href="{linkHref || '#'}"
data-variant="link"
@click="selectAction(event, { label: linkLabel, href: linkHref })"
>{linkLabel}</a>
{/if}
</div>
{/if}
</div>
{#if dismissible}
<button
type="button"
class="wire-next__alert-dismiss"
aria-label="{dismissLabel}"
@click="dismissAlert(event)"
>
<span class="icon-[lucide--x]" aria-hidden="true"></span>
</button>
{/if}
</section>
}
}