145 lines
6.5 KiB
Plaintext
145 lines
6.5 KiB
Plaintext
component Footer {
|
|
props {
|
|
@event select = function
|
|
@event action = function
|
|
size = "default"
|
|
color = "primary"
|
|
label = "Footer navigation"
|
|
items = []
|
|
columns = 3
|
|
maxWidth = "compact"
|
|
copyright = ""
|
|
class = ""
|
|
}
|
|
|
|
view {
|
|
<footer
|
|
{...attrs}
|
|
data-ui-component="Footer"
|
|
data-size='{size}'
|
|
data-color='{color}'
|
|
class='wire-footer border-t border-[var(--wire-color-border)] bg-[var(--wire-color-surface-raised)] text-[var(--wire-color-text)] {class}'
|
|
>
|
|
<slot name="pre-footer"></slot>
|
|
|
|
<div
|
|
class="wire-footer__inner mx-auto w-full px-4 py-12 sm:px-6 lg:px-8"
|
|
class:max-w-5xl='maxWidth === "compact"'
|
|
class:max-w-7xl='maxWidth === "wide" || maxWidth === "xl"'
|
|
class:max-w-screen-2xl='maxWidth === "full"'
|
|
class:py-8='size === "compact"'
|
|
class:py-16='size === "spacious"'
|
|
>
|
|
<nav aria-label='{label}'>
|
|
<div class='wire-footer__columns wire-footer--columns-{columns}'>
|
|
{#each items as item, itemIndex}
|
|
{#if item.type === "header"}
|
|
<section class="wire-footer__column" aria-labelledby='footer-heading-{itemIndex}'>
|
|
<h2 id='footer-heading-{itemIndex}' class="wire-footer__heading">
|
|
{item.label || item.title}
|
|
</h2>
|
|
|
|
{#if item.description}
|
|
<p class="wire-footer__description">{item.description}</p>
|
|
{/if}
|
|
|
|
{#if (item.items || item.links || []).length > 0}
|
|
<ul class="wire-footer__column-links">
|
|
{#each item.items || item.links || [] as child, childIndex}
|
|
<li>
|
|
<a
|
|
href='{child.href || "#"}'
|
|
target='{child.target || ""}'
|
|
rel='{child.external ? "noopener noreferrer" : (child.rel || "")}'
|
|
class="wire-footer__link"
|
|
@click='event.currentTarget.dispatchEvent(new CustomEvent("select", { bubbles: true, detail: { item: child, parent: item, itemIndex: childIndex, sectionIndex: itemIndex } })); child.action && event.currentTarget.dispatchEvent(new CustomEvent("action", { bubbles: true, detail: { item: child, parent: item, itemIndex: childIndex, sectionIndex: itemIndex } }))'
|
|
>
|
|
{#if child.icon}
|
|
<span class='{child.icon}' aria-hidden="true"></span>
|
|
{/if}
|
|
<span>{child.label || child.title}</span>
|
|
{#if child.external}
|
|
<span class="icon-[lucide--external-link]" aria-hidden="true"></span>
|
|
{/if}
|
|
</a>
|
|
</li>
|
|
{/each}
|
|
</ul>
|
|
{/if}
|
|
</section>
|
|
{:else if item.type === "link" || item.href}
|
|
<section class="wire-footer__column">
|
|
<ul class="wire-footer__column-links">
|
|
<li>
|
|
<a
|
|
href='{item.href || "#"}'
|
|
target='{item.target || ""}'
|
|
rel='{item.external ? "noopener noreferrer" : (item.rel || "")}'
|
|
class="wire-footer__link"
|
|
@click='event.currentTarget.dispatchEvent(new CustomEvent("select", { bubbles: true, detail: { item: item, itemIndex: itemIndex } })); item.action && event.currentTarget.dispatchEvent(new CustomEvent("action", { bubbles: true, detail: { item: item, itemIndex: itemIndex } }))'
|
|
>
|
|
{#if item.icon}
|
|
<span class='{item.icon}' aria-hidden="true"></span>
|
|
{/if}
|
|
<span>{item.label || item.title}</span>
|
|
{#if item.external}
|
|
<span class="icon-[lucide--external-link]" aria-hidden="true"></span>
|
|
{/if}
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</section>
|
|
{:else}
|
|
<section class="wire-footer__column">
|
|
{#if item.title || item.label}
|
|
<h2 class="wire-footer__heading">{item.title || item.label}</h2>
|
|
{/if}
|
|
{#if item.description}
|
|
<p class="wire-footer__description">{item.description}</p>
|
|
{/if}
|
|
<ul class="wire-footer__column-links">
|
|
{#each item.items || item.links || [] as child, childIndex}
|
|
<li>
|
|
<a
|
|
href='{child.href || "#"}'
|
|
target='{child.target || ""}'
|
|
rel='{child.external ? "noopener noreferrer" : (child.rel || "")}'
|
|
class="wire-footer__link"
|
|
@click='event.currentTarget.dispatchEvent(new CustomEvent("select", { bubbles: true, detail: { item: child, parent: item, itemIndex: childIndex, sectionIndex: itemIndex } })); child.action && event.currentTarget.dispatchEvent(new CustomEvent("action", { bubbles: true, detail: { item: child, parent: item, itemIndex: childIndex, sectionIndex: itemIndex } }))'
|
|
>
|
|
{#if child.icon}
|
|
<span class='{child.icon}' aria-hidden="true"></span>
|
|
{/if}
|
|
<span>{child.label || child.title}</span>
|
|
{#if child.external}
|
|
<span class="icon-[lucide--external-link]" aria-hidden="true"></span>
|
|
{/if}
|
|
</a>
|
|
</li>
|
|
{/each}
|
|
</ul>
|
|
</section>
|
|
{/if}
|
|
{/each}
|
|
</div>
|
|
</nav>
|
|
|
|
<div class="wire-footer__copyright">
|
|
<div class="wire-footer__copyright-left">
|
|
<slot name="copyright-left"></slot>
|
|
{#if copyright}
|
|
<p>{copyright}</p>
|
|
{/if}
|
|
</div>
|
|
|
|
<div class="wire-footer__copyright-right">
|
|
<slot name="copyright-right"></slot>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<slot name="post-footer"></slot>
|
|
</footer>
|
|
}
|
|
}
|