Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 74 additions & 4 deletions src/components/footer/footer.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,29 @@
import { StylesheetManager } from '../../core/styles/stylesheet-utils';
import { style } from './footer.style';

// TypeScript declarations for Osano global object
declare global {
interface Window {
Osano?: {
cm?: {
hideWidget?: () => void;
showDrawer?: () => void;
};
};
}
}

/**
* @element lfx-footer
* @summary A footer component for LFX applications
* @description This component provides a consistent footer across LFX applications with optional cookie consent script integration
* @description This component provides a consistent footer across LFX applications with optional cookie consent script integration. When cookie tracking is enabled, it includes a "Manage cookie preferences" link that opens the Osano consent management drawer.
* @csspart footer - The main footer element
* @csspart footer-container - The main container of the footer
* @csspart footer-content - The content wrapper of the footer
* @csspart copyright - The copyright paragraph
* @csspart link - Individual footer links
* @csspart cookie-preferences - The cookie preferences container
* @csspart cookie-preferences-link - The cookie preferences link
*
* @cssproperty --lfx-footer-bg - Background color of the footer
* @cssproperty --lfx-footer-text - Text color of the footer
Expand All @@ -22,7 +36,7 @@ import { style } from './footer.style';
* @cssproperty --lfx-footer-font-size - Font size of footer text
* @cssproperty --lfx-footer-font-family - Font family of footer text
*
* @attr {boolean} cookie-tracking - When true, appends the Osano cookie consent script to the document
* @attr {boolean} cookie-tracking - When true, appends the Osano cookie consent script to the document and shows the "Manage cookie preferences" link
*
* @fires cookie-script-error - Fired when the cookie consent script fails to load
*/
Expand All @@ -41,7 +55,7 @@ export class LFXFooter extends HTMLElement {
return ['cookie-tracking'];
}

attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {
attributeChangedCallback(name: string): void {
if (name === 'cookie-tracking' && this._rendered) {
this._handleCookieTracking();
}
Expand All @@ -61,6 +75,9 @@ export class LFXFooter extends HTMLElement {
and <a href="https://www.linuxfoundation.org/legal/trademark-usage?hsLang=en" target="_blank" rel="noopener noreferrer" part="link">Trademark Usage</a>,
please see our <a href="https://www.linuxfoundation.org/legal/policies" target="_blank" rel="noopener noreferrer" part="link">Policies</a> page.
</p>
<div class="cookie-preferences" part="cookie-preferences" style="display: none;">
<a href="#" class="cookie-preferences-link" part="cookie-preferences-link">Manage cookie preferences</a>.
</div>
</div>
</div>
</footer>
Expand All @@ -78,16 +95,45 @@ export class LFXFooter extends HTMLElement {
this._rendered = true;
}

// Set up cookie preferences link
this._setupCookiePreferencesLink();

// Check if cookie tracking should be enabled
this._handleCookieTracking();
}

private _setupCookiePreferencesLink(): void {
const cookiePreferencesLink = this.shadowRoot?.querySelector('.cookie-preferences-link');
if (cookiePreferencesLink) {
cookiePreferencesLink.addEventListener('click', this._handleCookiePreferencesClick.bind(this));
}
}

private _handleCookiePreferencesClick(event: Event): void {
event.preventDefault();

// Show the Osano drawer
if (typeof window !== 'undefined' && window.Osano?.cm?.showDrawer) {
window.Osano.cm.showDrawer();
} else {
console.warn('LFXFooter: Osano CMP not available for showing cookie preferences drawer');
}
}

private _handleCookieTracking(): void {
const cookieTrackingAttr = this.getAttribute('cookie-tracking');
const shouldEnable = cookieTrackingAttr === 'true' || cookieTrackingAttr === '';

if (shouldEnable) {
this._appendOsanoScript();
this._showCookiePreferencesLink();
}
}

private _showCookiePreferencesLink(): void {
const cookiePreferences = this.shadowRoot?.querySelector('.cookie-preferences') as HTMLElement;
if (cookiePreferences) {
cookiePreferences.style.display = 'inline';
}
}

Expand All @@ -102,7 +148,28 @@ export class LFXFooter extends HTMLElement {
return;
}

// Create and append the script
// Add Osano initialization script first
const initScript = document.createElement('script');
initScript.textContent = `
(function (w, o, d) {
w[o] =
w[o] ||
function () {
w[o][d].push(arguments);
};
w[o][d] = w[o][d] || [];
})(window, 'Osano', 'data');

// Hide widget on initialization
window.Osano('onInitialized', function(consent) {
// Add style to hide widget
const style = document.createElement('style');
style.textContent = '.osano-cm-widget {display: none !important;}';
document.head.appendChild(style);
});
`;

// Create and append the main Osano script
const script = document.createElement('script');
script.src = LFXFooter.OSANO_SCRIPT_SRC;
script.async = true;
Expand All @@ -122,9 +189,12 @@ export class LFXFooter extends HTMLElement {
);
};

// Append both scripts to the document
if (document.head) {
document.head.appendChild(initScript);
document.head.appendChild(script);
} else {
document.body?.appendChild(initScript);
document.body?.appendChild(script);
}
}
Expand Down
26 changes: 26 additions & 0 deletions src/components/footer/footer.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,32 @@ export const style = `
outline-offset: var(--lfx-footer-link-focus-offset, 2px);
}

.cookie-preferences {
margin-top: 0.5rem;
}

.cookie-preferences a {
color: var(--lfx-footer-link-color, #5b6367);
text-decoration: var(--lfx-footer-link-decoration, none);
transition: var(--lfx-footer-link-transition, color 0.2s ease);
}

.cookie-preferences a:hover {
color: var(--lfx-footer-link-hover-color, #5b6367);
text-decoration: var(--lfx-footer-link-hover-decoration, underline);
}

.cookie-preferences a:focus {

.cookie-preferences a:focus {
outline: var(--lfx-footer-link-focus-outline, 2px solid currentColor);
outline-offset: var(--lfx-footer-link-focus-offset, 2px);
}

.osano-cm-widget {
display: none !important;
}

/* Responsive adjustments */
@media (max-width: 768px) {
:host {
Expand Down