/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/
import {LitElement, html, css, unsafeCSS} from 'lit';
import {customElement, property} from 'lit/decorators.js';
import { breakpoints } from '../../breakpoints';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
@customElement('iu-contact-card')
export class ContactCard extends LitElement {
static override styles = css`
:host{
display: flex;
align-items: flex-end;
aspect-ratio: 1/1;
background: var(--iu-color-black);
color: var(--iu-color-yellow-100);
padding: var(--iu-grid-gutter);
}
:host(.external) a svg{
transform: rotate(-45deg);
}
:host(.span-2){
aspect-ratio: unset;
}
@media ${unsafeCSS(breakpoints.xl)} {
:host(.span-2){
aspect-ratio: 2/0.975;
}
}
div{
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
header{
flex-grow: 1;
}
header span{
display: block;
}
.title{
font: var(--iu-f-lg);
}
.sub{
margin-top: 1rem;
}
header a{
display: flex;
text-decoration: none;
color: var(--iu-color-yellow-100);
}
header a span{
flex-grow: 1;
}
header a svg{
width: 40px;
flex-shrink: 0;
margin-top: 10px;
}
@media ${unsafeCSS(breakpoints.lg)} {
:host(.span-2) footer{
display: grid;
grid-template-columns: repeat(2,1fr);
}
}
footer ul{
list-style-type: none;
margin: 0;
padding: 0;
}
footer ul li a{
color: var(--iu-color-yellow-100);
}
footer ul li a:hover{
text-decoration: none;
}
.description{
margin-top: var(--iu-spacing-6);
}
@media ${unsafeCSS(breakpoints.xl)} {
.description{
margin-top: 0;
}
}
.description p{
margin: 0;
}
`;
@property() href? : string;
@property() name : string = '#';
@property() sub? : string;
@property({ type: Array }) contacts?: Array<{ href: string; label: string }> = [];
@property() description? : string;
/**
* Checks if a link is external or internal.
* @param link The URL to check.
* @returns true if the link is external, false otherwise.
*/
private isExternalLink(link: string): boolean {
// const linkElement = document.createElement('a');
// linkElement.href = link;
// return linkElement.hostname !== window.location.hostname && !!linkElement.hostname;
try {
const url = new URL(link, window.location.href);
const hostname = url.hostname;
return !(hostname === 'iuav.it' || hostname === 'www.iuav.it');
} catch {
return false; // treat invalid or relative URLs as internal
}
}
/**
* Applies the appropriate class to the component based on the link type.
*/
private checkLinkType() {
if (this.href) {
const isExternal = this.isExternalLink(this.href);
this.classList.toggle('external', isExternal);
this.classList.toggle('internal', !isExternal);
}
}
/**
* If component has description, span for 2 columns
*/
private checkCardSpan(){
if (this.description != undefined) {
this.classList.add('span-2')
}
}
override firstUpdated(){
super.firstUpdated();
this.checkCardSpan();
this.checkLinkType();
}
override render() {
return html`
<div>
<header>
${this. href
? html`<a href="${this.href}" class="title"><span>${this.name}</span><svg width="27" height="20" viewBox="0 0 27 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M16.6667 1L25 10M25 10L16.6667 19M25 10H0" stroke="#FFCC00" stroke-width="2"/></svg></a>`
: html`<span class="title">${this.name}</span>`
}
${this.sub && html`<span class="sub">${this.sub}</span>`}
</header>
<footer>
${this.contacts && html`
<ul>
${this.contacts.map(
(contact) => html`
<li><a href="${contact.href}">${unsafeHTML(contact.label)}</a></li>
`
)}
</ul>
${this.description && html`
<div class="description"><p>${this.description}</p></div>
`}
`}
</footer>
</div>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
'iu-contact-card': ContactCard;
}
}