diff --git a/.vscode/settings.json b/.vscode/settings.json
index dba6f75..e0f29f3 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -23,6 +23,7 @@
},
"cSpell.words": [
"csspart",
- "cssproperty"
+ "cssproperty",
+ "Osano"
]
}
diff --git a/README.md b/README.md
index 1476ad4..cf78cc2 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,9 @@ npm install @linuxfoundation/lfx-ui-core
- [Design Tokens](docs/design-tokens.md)
- [Prettier Configuration](docs/prettier-config.md)
- Components
+ - [Components Overview](docs/components.md)
- [Footer Component](docs/footer.md)
+ - [Tools Component](docs/tools.md)
## Contributing
diff --git a/docs/components.md b/docs/components.md
new file mode 100644
index 0000000..de375fe
--- /dev/null
+++ b/docs/components.md
@@ -0,0 +1,170 @@
+# LFX UI Core Components
+
+This document provides an overview of all available components in the LFX UI Core package.
+
+## Available Components
+
+### Footer Component (`lfx-footer`)
+
+A comprehensive footer component that provides consistent copyright and legal information across LFX applications.
+
+**Key Features:**
+
+- **Cookie Consent Integration**: Optional Osano cookie consent script loading
+- **Extensive Customization**: CSS custom properties for complete theming
+- **Accessibility**: Built-in accessibility features and semantic HTML
+- **Responsive Design**: Mobile-optimized with responsive breakpoints
+- **CSS Parts**: Fine-grained styling control with CSS parts
+
+**Usage:**
+
+```html
+
+
+
+
+
+
+
+
+```
+
+**Documentation:** [Footer Component](footer.md)
+
+### Tools Component (`lfx-tools`)
+
+A tools menu component that provides a grid icon button that opens a dropdown menu with various LFX tools and applications.
+
+**Key Features:**
+
+- **Dynamic Menu**: Configurable menu structure with sections and items
+- **Font Awesome Integration**: Support for Font Awesome Pro icons
+- **Active State Management**: Automatic highlighting of current product
+- **Accessibility**: Proper ARIA attributes and keyboard navigation
+- **Customizable Styling**: CSS custom properties for theming
+
+**Usage:**
+
+```html
+
+
+
+
+
+
+
+
+```
+
+**Documentation:** [Tools Component](tools.md)
+
+## Component Features Overview
+
+| Feature | Footer | Tools |
+| --------------------- | ------ | ----- |
+| Cookie Tracking | ✅ | ❌ |
+| CSS Custom Properties | ✅ | ✅ |
+| CSS Parts | ✅ | ✅ |
+| Accessibility | ✅ | ✅ |
+| Responsive Design | ✅ | ✅ |
+| Framework Agnostic | ✅ | ✅ |
+| TypeScript Support | ✅ | ✅ |
+
+## Installation and Setup
+
+### Basic Installation
+
+```bash
+npm install @linuxfoundation/lfx-ui-core
+```
+
+### Import Components
+
+```typescript
+// Import all components
+import '@linuxfoundation/lfx-ui-core';
+
+// Or import individual components
+import '@linuxfoundation/lfx-ui-core/dist/components/footer';
+import '@linuxfoundation/lfx-ui-core/dist/components/tools';
+```
+
+### Framework Integration
+
+#### Angular
+
+```typescript
+// In main.ts or app.module.ts
+import '@linuxfoundation/lfx-ui-core';
+```
+
+#### Vue
+
+```typescript
+// In main.js
+import '@linuxfoundation/lfx-ui-core';
+```
+
+#### React
+
+```typescript
+// In your main component or index file
+import '@linuxfoundation/lfx-ui-core';
+```
+
+## Design System Integration
+
+All components are built to work seamlessly with the LFX design system:
+
+- **Design Tokens**: Components use semantic design tokens for consistent theming
+- **Theme Support**: Automatic integration with PrimeOne theme system
+- **Customization**: Extensive CSS custom properties for framework-specific theming
+- **Accessibility**: Built-in accessibility features following WCAG guidelines
+
+## Development
+
+### Storybook
+
+Run Storybook to explore all components and their variations:
+
+```bash
+npm run storybook
+```
+
+Navigate to [http://localhost:6006](http://localhost:6006) to view the component library.
+
+### Building
+
+```bash
+npm run build
+```
+
+### Testing
+
+```bash
+npm test
+```
+
+## Contributing
+
+When adding new components:
+
+1. Follow the established component structure and patterns
+2. Include comprehensive JSDoc documentation
+3. Create Storybook stories for all variations
+4. Add accessibility features and tests
+5. Update this documentation
+6. Follow the TypeScript and vanilla web component standards
+
+## Browser Support
+
+All components support:
+
+- Chrome 88+
+- Firefox 85+
+- Safari 14+
+- Edge 88+
+
+## License
+
+MIT License - see [LICENSE](../LICENSE) for details.
diff --git a/docs/footer.md b/docs/footer.md
index 454693f..8d96193 100644
--- a/docs/footer.md
+++ b/docs/footer.md
@@ -1,6 +1,6 @@
# Footer Component
-The footer component provides a consistent bottom section for your application with comprehensive styling options. Here's how to implement and customize it across different frameworks.
+The footer component provides a consistent bottom section for your application with comprehensive styling options and optional cookie consent script integration. Here's how to implement and customize it across different frameworks.
## Basic Usage
@@ -52,6 +52,107 @@ Then, use the component in your HTML:
Example: [https://stackblitz.com/edit/vitejs-vite-vn2ysk?file=index.html](https://stackblitz.com/edit/vitejs-vite-vn2ysk?file=index.html)
+## Features
+
+### Cookie Consent Integration
+
+The footer component can automatically load the Osano cookie consent script when the `cookie-tracking` attribute is present:
+
+```html
+
+
+
+
+
+
+
+
+
+
+
+```
+
+**Important Notes:**
+
+- The script will only be loaded once, even if multiple footer components have cookie tracking enabled
+- The script is loaded asynchronously for better performance
+- The component automatically handles script deduplication
+- Works in both browser and server-side rendering environments
+- Includes error handling for script loading failures
+
+### Error Handling
+
+The component provides error handling for script loading failures:
+
+```javascript
+const footer = document.querySelector('lfx-footer');
+
+footer.addEventListener('cookie-script-error', (event) => {
+ console.error('Cookie script failed to load:', event.detail.error);
+ // Implement fallback behavior if needed
+});
+```
+
+**Error Event Details:**
+
+- `event.detail.scriptSrc`: The script URL that failed to load
+- `event.detail.error`: Error description
+
+### Framework-Specific Cookie Tracking
+
+#### Angular
+
+```typescript
+// In your component template
+
+
+// In your component class
+export class AppComponent {
+ enableCookieTracking = true;
+}
+```
+
+#### Vue
+
+```vue
+
+
+
+
+
+```
+
+#### React
+
+```jsx
+function App() {
+ const [enableCookieTracking, setEnableCookieTracking] = useState(true);
+
+ return ;
+}
+```
+
+## Attributes
+
+| Attribute | Type | Description | Default |
+| ----------------- | ------- | ------------------------------------------ | ------- |
+| `cookie-tracking` | boolean | Enable Osano cookie consent script loading | `false` |
+
+**Boolean Attribute Behavior:**
+
+- `cookie-tracking` (no value) = enabled
+- `cookie-tracking="true"` = enabled
+- `cookie-tracking="false"` = disabled
+- No attribute = disabled
+
## Styling and Customization
The footer component is highly customizable using CSS custom properties. Here are the available styling options:
diff --git a/package.json b/package.json
index d062173..b2dee1f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@linuxfoundation/lfx-ui-core",
- "version": "0.0.17-alpha.2",
+ "version": "0.0.0",
"description": "LFX UI Core Configurations and Components",
"main": "dist/index.js",
"types": "dist/index.d.ts",
diff --git a/src/components/footer/footer.component.ts b/src/components/footer/footer.component.ts
index 384504b..b068429 100644
--- a/src/components/footer/footer.component.ts
+++ b/src/components/footer/footer.component.ts
@@ -7,7 +7,7 @@ import { style } from './footer.style';
/**
* @element lfx-footer
* @summary A footer component for LFX applications
- * @description This component provides a consistent footer across LFX applications
+ * @description This component provides a consistent footer across LFX applications with optional cookie consent script integration
* @csspart footer - The main footer element
* @csspart footer-container - The main container of the footer
* @csspart footer-content - The content wrapper of the footer
@@ -21,10 +21,15 @@ import { style } from './footer.style';
* @cssproperty --lfx-footer-padding - Padding of the footer
* @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
+ *
+ * @fires cookie-script-error - Fired when the cookie consent script fails to load
*/
export class LFXFooter extends HTMLElement {
private _template!: HTMLTemplateElement;
private _rendered = false;
+ private static readonly OSANO_SCRIPT_SRC = 'https://cmp.osano.com/16A0DbT9yDNIaQkvZ/d6ac078e-c71f-4b96-8c97-818cc1cc6632/osano.js?variant=two';
constructor() {
super();
@@ -32,6 +37,16 @@ export class LFXFooter extends HTMLElement {
this._createTemplate();
}
+ static get observedAttributes(): string[] {
+ return ['cookie-tracking'];
+ }
+
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {
+ if (name === 'cookie-tracking' && this._rendered) {
+ this._handleCookieTracking();
+ }
+ }
+
private _createTemplate(): void {
this._template = document.createElement('template');
this._template.innerHTML = `
@@ -62,6 +77,56 @@ export class LFXFooter extends HTMLElement {
this.shadowRoot!.appendChild(content);
this._rendered = true;
}
+
+ // Check if cookie tracking should be enabled
+ this._handleCookieTracking();
+ }
+
+ private _handleCookieTracking(): void {
+ const cookieTrackingAttr = this.getAttribute('cookie-tracking');
+ const shouldEnable = cookieTrackingAttr === 'true' || cookieTrackingAttr === '';
+
+ if (shouldEnable) {
+ this._appendOsanoScript();
+ }
+ }
+
+ private _appendOsanoScript(): void {
+ if (typeof document === 'undefined') {
+ return;
+ }
+
+ // Check if the script already exists to prevent duplicates
+ const existingScript = document.querySelector(`script[src="${LFXFooter.OSANO_SCRIPT_SRC}"]`);
+ if (existingScript) {
+ return;
+ }
+
+ // Create and append the script
+ const script = document.createElement('script');
+ script.src = LFXFooter.OSANO_SCRIPT_SRC;
+ script.async = true;
+
+ // Add error handling
+ script.onerror = () => {
+ console.error('LFXFooter: Failed to load Osano cookie consent script');
+ // Dispatch custom event for error handling
+ this.dispatchEvent(
+ new CustomEvent('cookie-script-error', {
+ bubbles: true,
+ detail: {
+ scriptSrc: LFXFooter.OSANO_SCRIPT_SRC,
+ error: 'Script failed to load',
+ },
+ })
+ );
+ };
+
+ if (document.head) {
+ document.head.appendChild(script);
+ } else {
+ document.body?.appendChild(script);
+ }
}
}
diff --git a/src/components/footer/footer.stories.ts b/src/components/footer/footer.stories.ts
index 7339488..8e5ac37 100644
--- a/src/components/footer/footer.stories.ts
+++ b/src/components/footer/footer.stories.ts
@@ -5,7 +5,7 @@ import { Meta, StoryObj } from '@storybook/web-components';
import { html } from 'lit';
import './footer.component';
-// Type for CSS custom properties
+// Type for CSS custom properties and attributes
interface FooterCSSProps {
'--lfx-footer-bg'?: string;
'--lfx-footer-text'?: string;
@@ -14,6 +14,7 @@ interface FooterCSSProps {
'--lfx-footer-padding'?: string;
'--lfx-footer-font-size'?: string;
'--lfx-footer-text-align'?: string;
+ 'cookie-tracking'?: boolean;
[key: string]: any;
}
@@ -27,6 +28,12 @@ const meta: Meta = {
component: `
A footer component that displays consistent copyright and legal information across LFX applications.
+## Features
+- **Cookie Tracking**: Enable Osano cookie consent script with the \`cookie-tracking\` attribute
+- **Customizable Styling**: Extensive CSS custom properties for theming
+- **Accessibility**: Semantic HTML with proper ARIA attributes
+- **Responsive**: Mobile-optimized design
+
## Styling
The footer can be styled using CSS custom properties for maximum flexibility:
@@ -46,6 +53,11 @@ Plus many more for advanced customization including responsive and accessibility
},
},
argTypes: {
+ 'cookie-tracking': {
+ control: 'boolean',
+ description: 'Enable Osano cookie consent script',
+ table: { category: 'Attributes' },
+ },
'--lfx-footer-bg': {
control: 'color',
description: 'Background color of the footer',
@@ -91,7 +103,7 @@ Plus many more for advanced customization including responsive and accessibility
return html`
-
+
`;
},
@@ -105,6 +117,25 @@ export const Default: Story = {
args: {},
};
+// Footer with cookie tracking enabled
+export const WithCookieTracking: Story = {
+ args: {
+ 'cookie-tracking': true,
+ },
+ parameters: {
+ docs: {
+ description: {
+ story: `
+This story demonstrates the footer with cookie tracking enabled. When the \`cookie-tracking\` attribute is set to \`true\`,
+the component will automatically append the Osano cookie consent script to the document head.
+
+**Note**: The script will only be added once, even if multiple footer components have cookie tracking enabled.
+ `,
+ },
+ },
+ },
+};
+
// Light theme
export const LightTheme: Story = {
args: {