${this.items.map(
- (item) => html`
-
+ (item, index) => html`
+

${item.caption
@@ -113,10 +138,10 @@
)}
-
+
-
-
+
+
`;
diff --git a/src/components/contacts/contact-card.ts b/src/components/contacts/contact-card.ts
index 52d2ab5..7ff47a9 100644
--- a/src/components/contacts/contact-card.ts
+++ b/src/components/contacts/contact-card.ts
@@ -52,7 +52,6 @@
}
header a{
display: flex;
- align-items: center;
text-decoration: none;
color: var(--iu-color-yellow-100);
}
@@ -61,6 +60,8 @@
}
header a svg{
width: 40px;
+ flex-shrink: 0;
+ margin-top: 10px;
}
@media ${unsafeCSS(breakpoints.lg)} {
:host(.span-2) footer{
@@ -104,9 +105,16 @@
* @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;
+ // 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
+ }
}
/**
diff --git a/src/components/events/event.ts b/src/components/events/event.ts
index 5143f36..b27f34f 100644
--- a/src/components/events/event.ts
+++ b/src/components/events/event.ts
@@ -14,6 +14,7 @@
static override styles = css`
:host{
display: block;
+ --iu-spacing-block: 0;
}
.event{
padding-top: var(--iu-spacing-2);
diff --git a/src/components/featured-content/featured-content.ts b/src/components/featured-content/featured-content.ts
index f4db571..c3dfa6e 100644
--- a/src/components/featured-content/featured-content.ts
+++ b/src/components/featured-content/featured-content.ts
@@ -66,7 +66,33 @@
@property() link = '';
@property() href = '';
@property() img = '';
- @property() text? = '';
+ // @TODO check if this is safe
+ @property({ type: String, converter: (value: string | null) => {
+ if (!value) return '';
+ // Create a new DOMParser
+ const parser = new DOMParser();
+ // Parse the HTML string
+ const doc = parser.parseFromString(value, 'text/html');
+ // Remove potentially dangerous elements and attributes
+ const sanitize = (document: Document) => {
+ // Only allow specific safe tags
+ const safeTags = ['p', 'b', 'i', 'em', 'strong', 'span', 'br'];
+ // Remove unsafe elements
+ Array.from(document.body.getElementsByTagName('*')).forEach(el => {
+ if (!safeTags.includes(el.tagName.toLowerCase())) {
+ el.remove();
+ }
+ // Remove all attributes except class
+ Array.from(el.attributes).forEach(attr => {
+ if (attr.name !== 'class') {
+ el.removeAttribute(attr.name);
+ }
+ });
+ });
+ return document.body.innerHTML;
+ };
+ return sanitize(doc);
+ }}) text? = '';
override render() {
return html`
diff --git a/src/components/header/header-layout.ts b/src/components/header/header-layout.ts
new file mode 100644
index 0000000..4fc4751
--- /dev/null
+++ b/src/components/header/header-layout.ts
@@ -0,0 +1,200 @@
+// src/components/iu-header.ts
+import { LitElement, html, css } from 'lit';
+import { customElement } from 'lit/decorators.js';
+
+@customElement('iu-header-layout')
+export class SiteHeaderLayout extends LitElement {
+
+ override render() {
+ return html`
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `;
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'iu-header-layout': SiteHeaderLayout;
+ }
+}
\ No newline at end of file
diff --git a/src/components/header/header-navbar-item.ts b/src/components/header/header-navbar-item.ts
index e3466ec..09035e8 100644
--- a/src/components/header/header-navbar-item.ts
+++ b/src/components/header/header-navbar-item.ts
@@ -56,6 +56,7 @@
// Lock body
document.body.style.top = `-${window.scrollY}px`;
document.body.style.position = 'fixed';
+ document.body.style.width = '100%';
} else {
// Remove and restore previous scroll position
document.body.style.top = '';
diff --git a/src/components/header/header-topbar-item.ts b/src/components/header/header-topbar-item.ts
index 076f25c..7fbbed4 100644
--- a/src/components/header/header-topbar-item.ts
+++ b/src/components/header/header-topbar-item.ts
@@ -22,10 +22,11 @@
@property() href = '';
@property() text = '';
+ @property() target = 'self';
override render() {
return html`
-
${this.text}
+
${this.text}
`;
}
diff --git a/src/components/hero-banner/hero-banner.ts b/src/components/hero-banner/hero-banner.ts
index cf35857..ad36d20 100644
--- a/src/components/hero-banner/hero-banner.ts
+++ b/src/components/hero-banner/hero-banner.ts
@@ -16,24 +16,26 @@
display:block;
margin-bottom: var(--iu-spacing-block-lg);
}
- .video{
+ .video, .img{
aspect-ratio: 16/9;
position: relative;
overflow: hidden;
- margin-bottom: calc(var(--iu-grid-gutter)*2);
z-index: 20;
}
+ .video{
+ margin-bottom: calc(var(--iu-grid-gutter)*2);
+ }
@media ${unsafeCSS(breakpoints.md)} {
- .video{
+ .video, .img{
aspect-ratio: auto;
}
}
@media ${unsafeCSS(breakpoints.lg)} {
- .video{
+ .video, .img{
height: calc(var(--iu-hero-banner-height) - var(--iu-grid-gutter));
}
}
- .video video{
+ .video video, .img img{
width: 100%;
height: 100%;
object-fit: cover;
diff --git a/src/components/link/link.css b/src/components/link/link.css
index 2d87223..6a32071 100644
--- a/src/components/link/link.css
+++ b/src/components/link/link.css
@@ -1,3 +1,3 @@
iu-link:last-child{
- border-bottom: 1px solid var(--iu-comp-border-color);
+ /* border-bottom: 1px solid var(--iu-comp-border-color); */
}
\ No newline at end of file
diff --git a/src/components/link/link.ts b/src/components/link/link.ts
index 5089284..02738eb 100644
--- a/src/components/link/link.ts
+++ b/src/components/link/link.ts
@@ -78,10 +78,23 @@
@property({type: Boolean, reflect: true}) nested?: boolean = false;
override render() {
+
+ let isExternal = false;
+ try {
+ const url = new URL(this.href ?? '', window.location.href);
+ const hostname = url.hostname;
+
+ // Match exactly 'iuav.it' or 'www.iuav.it'
+ isExternal = !(hostname === 'iuav.it' || hostname === 'www.iuav.it');
+ } catch {
+ // If it's a relative URL or invalid, treat as internal
+ isExternal = false;
+ }
+
return html`
- ${this.label
+ ${isExternal
? html`
`
: html`
diff --git a/src/components/link/links-list.ts b/src/components/link/links-list.ts
index 6caddfd..101055e 100644
--- a/src/components/link/links-list.ts
+++ b/src/components/link/links-list.ts
@@ -16,7 +16,7 @@
display: block;
margin-bottom: var(--iu-spacing-block);
}
- .columns-1{
+ .columns-2{
width: 50%;
}
p{
@@ -28,19 +28,24 @@
`;
@property() label = 'Per approfondire';
- @property({ type: Number }) columns = 1;
- @property({ type: Array }) items: Array<{ href: string; text: string }> = [];
+ @property({ type: Number }) columns = 2;
+ // @property({ type: Array }) items: Array<{ href: string; text: string }> = [];
+ @property({ type: String }) items = '[]';
+
+ get parsedItems() {
+ try {
+ return JSON.parse(this.items);
+ } catch {
+ return [];
+ }
+ }
override render() {
return html`
${this.label && html`
${this.label}
`}
- ${this.items.map(
- (item) => html`
-
- `
- )}
+ ${this.parsedItems.map(item => html`
`)}
`;
diff --git a/src/components/main.ts b/src/components/main.ts
index 04aafdd..8840bf8 100644
--- a/src/components/main.ts
+++ b/src/components/main.ts
@@ -28,6 +28,7 @@
export { SiteHeaderNavbarItem } from './header/header-navbar-item';
export { SiteHeaderNavbarSubmenu } from './header/header-navbar-submenu';
export { SiteHeaderNavbarSubmenuSection } from './header/header-navbar-submenu-section';
+export { SiteHeaderLayout } from './header/header-layout';
export { SiteHeaderNavbar } from './header/header-navbar';
export { SiteHeaderTopbarItem } from './header/header-topbar-item';
export { SiteHeaderTopbar } from './header/header-topbar';
@@ -41,3 +42,4 @@
export { NavCard } from './card/nav-card';
export { Paragraph } from './paragraph/paragraph';
export { SocialNav } from './social/social-nav';
+export { PageCard } from './card/page-card';
diff --git a/src/components/paragraph/paragraph.ts b/src/components/paragraph/paragraph.ts
index 1b6d990..869f9a4 100644
--- a/src/components/paragraph/paragraph.ts
+++ b/src/components/paragraph/paragraph.ts
@@ -8,7 +8,8 @@
static override styles = css`
:host{
display: block;
- margin-bottom: var(--iu-spacing-block-xs);
+ // margin-bottom: var(--iu-spacing-block-xs);
+ margin-bottom: var(--iu-spacing-block-sm);
}
@media ${unsafeCSS(breakpoints.lg)} {
.column-1{
@@ -27,7 +28,8 @@
}
@media ${unsafeCSS(breakpoints.md)} {
.fs-3{
- --iu-p-f: var(--iu-f-2);
+ --iu-p-f: var(--iu-f-2);
+ max-width: 90%
}
}
@media ${unsafeCSS(breakpoints.xl)} {
@@ -45,7 +47,7 @@
}
`;
- @property({type: Number}) columns: number = 2;
+ @property({type: Number}) columns: number = 1;
@property({type: Number}) size = 1;
@property({type: Boolean, reflect: true}) nested?: boolean = false;