diff --git a/components/footer/README.md b/components/footer/README.md new file mode 100755 index 0000000000..2465c824b2 --- /dev/null +++ b/components/footer/README.md @@ -0,0 +1,96 @@ +# Footer component + +[![npm version](https://badge.fury.io/js/%40visual-framework%2Fvf-footer.svg)](https://badge.fury.io/js/%40visual-framework%2Fvf-footer) + +## About + +The footer is a component positioned at the bottom of a page that provides access to supporting navigation, brand identity, and regulatory information. + +## Usage + +### Description + +The footer marks the end of the page experience. It reinforces brand presence, helps users discover supporting links, and provides access to required legal and compliance information. While it complements primary navigation, it should not duplicate or replace core page content. Its structure and scale vary by context from modular configurations to simplified variations for focused experiences. + +### When to use this component? + +Use the footer when the page provides a complete experience and users may benefit from secondary navigation or supporting information. + +Here are some cases where the footer provides value: + +- The experience extends beyond a single interaction and requires familiar structural anchors. +- Users may reach the end of the page seeking additional options or clarification. +- Support pathways should remain available without competing with primary actions. +- Social engagement should be accessible without interfering with the main content structure. +- The page represents a natural end point where related links can guide next steps. +- Regulatory or compliance requirements demand persistent access. +- Brand identity and organisational representation standards apply. + +### When not to use this component? + +The footer should be omitted when: + +- Users are completing a focused workflow that benefits from minimal navigation. +- The page exists within an embedded or constrained environment. +- The layout requires a minimal footprint. +- A modal, micro-interaction, or contained workflow does not represent a full-page experience. + +### Deciding what to use + +| Variant | Examples | Description | +| --- | --- | --- | +| [Modular](../vf-footer) | VF-footer | Use when footer sections need to be customised | +| EMBL-EBI Corporate Variant | [EMBL_EBI header-footer](../ebi-header-footer) | Use the EMBL-EBI corporate variant for organisational or self-contained experiences | +| | [Minimal](../vf-minimal-footer) | Use when only essential brand and legal information is needed | + +### Themes + +The footer is available in two colour schemes: light and dark, to establish clear visual distinction from page content. + +Apply the light scheme when the page background uses colour or tone, and the dark scheme when the background is white or near-white. This intentional contrast ensures users can clearly identify where the main content concludes and the footer begins. + +### Usability and content guidance + +Curate your footer. Footer links should direct users to relevant content that addresses common questions or needs. While disclaimers and legal content may be necessary, aim to keep them concise and avoid unnecessary clutter. + +The footer does not need to mirror the header. Link organisation in the footer may differ from top-level header navigation, particularly when the header contains more extensive navigation options than the footer can accommodate. + +### Collaboration + +The collaborations section provides standardised patterns for displaying varying levels of partnerships and collaborations. The display format adapts based on the number of collaborators. + +### Accessibility + +This component targets WCAG 2.1 AA accessibility standard. + +- Links provide direct location description [Manual testing required]: Ensure link text is descriptive and not ambiguous. WCAG A 2.4.4 Link purpose (in context) +- Keyboard navigation: All links and interactive elements are keyboard accessible +- Focus indicators: Clear visual focus states meet 3:1 contrast requirements +- Touch targets: All clickable elements meet the minimum 44x44 pixel touch target size on mobile and tablet +- Colour contrast: Text and link colours have been tested against both light and dark backgrounds +- Screen readers: Semantic HTML and ARIA labels ensure footer content is properly announced +- Responsive design: Footer adapts appropriately across mobile (600px), tablet (768px) and desktop (1154px) breakpoints + +## Install + +This component is distributed with npm. After [installing npm](https://www.npmjs.com/get-npm), you can install the `footer` with this command. + +``` +$ yarn add --dev @visual-framework/footer +``` + +### Sass/CSS + +The source files included are written in [Sass](http://sass-lang.com)(`scss`). You can point your Sass `include-path` at your `node_modules` directory and import it like this. + +``` +@import "@visual-framework/footer/index.scss"; +``` + +Make sure you import Sass requirements along with the modules. You can use a [project boilerplate](https://stable.visual-framework.dev/building/) or the [`vf-sass-starter`](https://stable.visual-framework.dev/components/vf-sass-starter/) + +## Help + +- [Read the Visual Framework troubleshooting](https://stable.visual-framework.dev/troubleshooting/) +- [Open a ticket](https://github.com/visual-framework/vf-core/issues) +- [Chat on Slack](https://join.slack.com/t/visual-framework/shared_invite/enQtNDAxNzY0NDg4NTY0LWFhMjEwNGY3ZTk3NWYxNWVjOWQ1ZWE4YjViZmY1YjBkMDQxMTNlNjQ0N2ZiMTQ1ZTZiMGM4NjU5Y2E0MjM3ZGQ) diff --git a/components/footer/assets/embl-ebi.png b/components/footer/assets/embl-ebi.png new file mode 100644 index 0000000000..11503463f3 Binary files /dev/null and b/components/footer/assets/embl-ebi.png differ diff --git a/components/footer/assets/minimal.png b/components/footer/assets/minimal.png new file mode 100644 index 0000000000..31db223747 Binary files /dev/null and b/components/footer/assets/minimal.png differ diff --git a/components/footer/assets/modular.png b/components/footer/assets/modular.png new file mode 100644 index 0000000000..a27e0af7e2 Binary files /dev/null and b/components/footer/assets/modular.png differ diff --git a/components/footer/footer.config.yml b/components/footer/footer.config.yml new file mode 100755 index 0000000000..9b347d1baf --- /dev/null +++ b/components/footer/footer.config.yml @@ -0,0 +1,9 @@ +title: Footer +label: Footer +preview: '@preview--nogrid' +status: live +context: + component-type: container + footer__url: 'JavaScript:Void(0);' + isExample: true + exampleMultiColumns: "false" diff --git a/components/footer/footer.njk b/components/footer/footer.njk new file mode 100755 index 0000000000..aa3b4b2c1f --- /dev/null +++ b/components/footer/footer.njk @@ -0,0 +1,3 @@ +Modular footer example +Minimal footer example +EMBL-EBI footer example diff --git a/components/vf-componenet-rollup/index.scss b/components/vf-componenet-rollup/index.scss index 32a00e31b9..07d75cfe54 100755 --- a/components/vf-componenet-rollup/index.scss +++ b/components/vf-componenet-rollup/index.scss @@ -138,6 +138,7 @@ button { @import 'vf-news-container/vf-news-container.scss'; @import 'vf-video-container/vf-video-container.scss'; +@import 'vf-minimal-footer/vf-minimal-footer.scss'; @import 'vf-footer/vf-footer.scss'; @import 'vf-show-more/vf-show-more.scss'; diff --git a/components/vf-footer/.npmignore b/components/vf-footer/.npmignore deleted file mode 100644 index cd8944a123..0000000000 --- a/components/vf-footer/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -bin -.github -.travis.yml -node_modules diff --git a/components/vf-footer/CHANGELOG.md b/components/vf-footer/CHANGELOG.md index c6cc60396e..3a60fd827b 100755 --- a/components/vf-footer/CHANGELOG.md +++ b/components/vf-footer/CHANGELOG.md @@ -1,3 +1,6 @@ +### 1.2.2 + +* Layout and styling updates including inner wrapper, spacing tokens, social icons, and mobile responsiveness improvements ### 1.2.1 * Changes to footer based on `EMBL-EBI Intranet` implementation findings [Tracking issue](https://github.com/visual-framework/vf-core/issues/1978) diff --git a/components/vf-footer/README.md b/components/vf-footer/README.md index 79aefb2fcc..18d8de179f 100755 --- a/components/vf-footer/README.md +++ b/components/vf-footer/README.md @@ -4,7 +4,134 @@ ## About -A container for links, copyright and other common content at the bottom of webpages. +The vf-footer is a flexible footer component that allows websites to configure different modules based on their specific needs whilst maintaining consistent branding. + +## Usage + +### Description + +The vf-footer provides a flexible and structured approach to footer configuration. It allows configuration of specific sections and adjustment of text content as needed, while maintaining consistent layout, accessibility compliance, and brand identity. + +### What does 'modular' mean? + +Modular in the context of the vf-footer refers to the ability to enable or disable sections and customise text within them. It does not mean you can change the order of sections. The visual sequence is fixed to maintain consistency and meet accessibility requirements. If your service requires a different section order, please contact the Visual Framework team to discuss your use case. + +### Configurable sections + +| Element | Usage | Notes | +| --- | --- | --- | +| Collaborations | Display partner, funder or collaborator logos | Optional | +| Custom logo | Highlight the specific branding | Optional | +| Mission statement | Provide context about the service or organisation | Optional | +| Custom links | Use website specific navigation organised by category. If custom navigation is not required, it is recommended to use the Minimal footer component instead | Required | +| Contact details | Contact details are flexible and can accommodate short or long text formats. All contact methods can be linked as needed, with the option to direct users to a dedicated contact page. | Optional | +| Social media | Link to relevant social channels | Optional | +| Utility | The bottom section contains links such as Terms of use, copyright and other utility links | Optional | + +### When to use + +Use the VF-Modular footer when your website requires: + +- To display social media channels +- Service-specific navigation or utility links +- Needs to display its own logo and mission statement +- Requires a flexible footer structure that can evolve +- Where there is a need to show collaboration with multiple partners + +### When not to use + +The Visual Framework offers other footer variants that may better suit other use cases: + +- If your site only needs basic branding, essential links, and legal information without service-specific navigation or social media, use Minimal footer instead +- If your site requires full EMBL-EBI institutional presence with parent navigation across all major organisational sections it is recommended to use the EMBL_EBI header-footer + +### Deciding what to use + +| Variant | Examples | Description | +| --- | --- | --- | +| [Modular](../vf-footer) | VF-footer | Use when footer sections need to be customised | +| EMBL-EBI Corporate Variant | [EMBL_EBI header-footer](../ebi-header-footer) | Use the EMBL-EBI corporate variant for organisational or self-contained experiences | +| | [Minimal](../vf-minimal-footer) | Use when only essential brand and legal information is needed | + +### Collaboration section variants + +The collaborations section provides standardised patterns for displaying varying levels of partnerships and collaborations. The display format adapts based on the number of collaborators. + +The Collaborations section renders its own top green border. Remove the footer's default top margin line to prevent duplication. + +#### Logos display (1 - 6 partners) + +When you have between 1 and 6 partners, display their logos horizontally across the section. + +- Uses a 6-column grid at desktop breakpoint (1154px+) +- One logo per column +- Maximum logo dimensions: 174px width and 64x height +- Logos centred within their column +- Scale down logos proportionally if they exceed maximum dimensions +- For best image resolution, svg usage is recommended + +#### Partners links in columns (1 - 9 partners) + +When you have between 1 and 9 partners, you need to display their names as text links. + +- 3-column layout on desktop +- Partner names displayed as clickable links +- Text aligned left within each column + +#### Categorised summary (10+ partners) + +When you have 10 or more partners, synthesise them into categories with summary numbers and a "See all collaborators" link. + +- Optional partnership statement describing the nature of collaborations +- Summary categories displayed as numbers with labels (e.g., "35 Data partners", "4 Supporting funders") +- "See all collaborators" link that directs to a dedicated page listing all partners +- Placeholder text can be customisable + +### Choosing the right collaboration variant + +| Variant | Nº of partners | Usage | +| --- | --- | --- | +| Logo display | 1 - 6 | Provides strong visual recognition for each partner | +| Text links in columns | 1 - 9 | Maintains readability whilst accommodating more partners | +| Categorised summary | 10+ | Prevents footer from becoming overwhelming; directs users to dedicated page | + +### Terms of Use (ToU) + +Guidelines for domains requiring both Organisation-wide and Service-specific Terms + +When a domain requires both organisation-wide Terms of Use and service-specific Terms of Use, teams should create a single dedicated page that clearly presents both sets of terms together. This consolidated approach ensures users can easily understand which terms apply to their specific use case while maintaining a single, clear ToU link in the footer. This prevents confusion from multiple links with similar names and provides a better user experience. + +#### Cookie banner pattern + +Avoid including ToU in cookie banners. Terms of Use should remain permanently visible in the footer rather than in a dismissible cookie consent banner. Cookie banners are temporary and can be dismissed by users, removing access to critical legal information. By keeping ToU in the footer, users can always access this information whenever needed, regardless of their cookie consent choices. + +### Themes + +The footer is available in two colour schemes: light and dark, to establish clear visual distinction from page content. + +Apply the light scheme when the page background uses colour or tone, and the dark scheme when the background is white or near-white. This intentional contrast ensures users can clearly identify where the main content concludes and the footer begins. + +### Responsiveness + +The component is designed to adapt seamlessly across different screen sizes. The layout of the custom links section wraps 2 column grids on tablet (Breaking point 768px) and 1 column on mobile (breaking point 600px). Spacing, readability, and target touch size are optimised for accessibility and ease of use. + +### Accessibility + +This component targets WCAG 2.1 AA accessibility standard. + +- Links provide direct location description [Manual testing required]: Ensure link text is descriptive and not ambiguous. WCAG A 2.4.4 Link purpose (in context) + +- Keyboard navigation: All links and interactive elements are keyboard accessible + +- Focus indicators: Clear visual focus states meet 3:1 contrast requirements + +- Touch targets: All clickable elements meet the minimum 44×44 pixel touch target size on mobile and tablet + +- Colour contrast: Text and link colours have been tested against both light and dark backgrounds + +- Screen readers: Semantic HTML and ARIA labels ensure footer content is properly announced + +- Responsive design: Footer adapts appropriately across mobile (600px), tablet (768px) and desktop (1154px) breakpoints ## Install diff --git a/components/vf-footer/assets/embl-ebi-rgb-all-white.png b/components/vf-footer/assets/embl-ebi-rgb-all-white.png new file mode 100644 index 0000000000..f257e59461 Binary files /dev/null and b/components/vf-footer/assets/embl-ebi-rgb-all-white.png differ diff --git a/components/vf-footer/assets/embl-ebi-rgb-full-colour.svg b/components/vf-footer/assets/embl-ebi-rgb-full-colour.svg new file mode 100644 index 0000000000..2074da77d2 --- /dev/null +++ b/components/vf-footer/assets/embl-ebi-rgb-full-colour.svg @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/vf-footer/assets/landscape-placeholder.svg b/components/vf-footer/assets/landscape-placeholder.svg new file mode 100644 index 0000000000..faea08cd58 --- /dev/null +++ b/components/vf-footer/assets/landscape-placeholder.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/components/vf-footer/package.json b/components/vf-footer/package.json index 0ad222c422..07aaa49c5c 100755 --- a/components/vf-footer/package.json +++ b/components/vf-footer/package.json @@ -1,5 +1,5 @@ { - "version": "1.2.1", + "version": "1.0.0-alpha.1", "name": "@visual-framework/vf-footer", "description": "vf-footer component", "homepage": "https://stable.visual-framework.dev/", diff --git a/components/vf-footer/vf-footer.config.yml b/components/vf-footer/vf-footer.config.yml index ab27c79b6a..345acdef1d 100755 --- a/components/vf-footer/vf-footer.config.yml +++ b/components/vf-footer/vf-footer.config.yml @@ -1,8 +1,31 @@ -title: Footer -label: Footer +title: Modular Footer +label: Modular Footer preview: '@preview--nogrid' status: live context: - exampleMultiColumns: "false" - component-type: block - footer__url: 'JavaScript:Void(0);' + footer__theme: 'dark' + component-type: container + hide-from-sitemenu: true + partner__variant: null +variants: + - name: dark + title: Dark + - name: light + title: Light + context: + footer__theme: 'light' + - name: partner logos + title: Partner Logos + context: + footer__theme: 'dark' + partner__variant: logos + - name: partner columns + title: Partner Columns + context: + footer__theme: 'dark' + partner__variant: columns + - name: partner summary + title: Partner Summary + context: + footer__theme: 'dark' + partner__variant: summary diff --git a/components/vf-footer/vf-footer.njk b/components/vf-footer/vf-footer.njk index 33f5372033..5279465de3 100755 --- a/components/vf-footer/vf-footer.njk +++ b/components/vf-footer/vf-footer.njk @@ -1,101 +1,264 @@ - \ No newline at end of file diff --git a/components/vf-footer/vf-footer.scss b/components/vf-footer/vf-footer.scss index 18e2cc0950..288270dd41 100755 --- a/components/vf-footer/vf-footer.scss +++ b/components/vf-footer/vf-footer.scss @@ -9,7 +9,7 @@ * Location: #{map-get($componentInfo, 'location')} */ -@import 'vf-footer.variables.scss'; +@import './vf-footer.variables.scss'; .vf-footer { background-color: color(grey--dark); @@ -49,47 +49,29 @@ } } -.vf-footer__notice { - @include set-type(text-body--3); - - color: ui-color(white); - max-width: 45em; -} - -.vf-footer__inner { - grid-column: main; - margin: 0 auto; - max-width: $vf-layout--comfortable; - padding: 0; -} - .vf-footer__legal { color: ui-color(white); column-gap: var(--page-grid-gap); grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + .vf-list { width: 100%; + font-size: 19px; } .vf-footer__legal-text, .vf-footer__link { font-size: 14px; + padding-top: 6px; + padding-bottom: 6px; } + .vf-footer__legal-text { color: color(grey--lightest); } - .vf-footer__link { - text-decoration: none; - } - .vf-list { - font-size: 19px; - } - - .vf-footer__legal-text, .vf-footer__link { - padding-top: 6px; - padding-bottom: 6px; + text-decoration: none; } @media (min-width: $vf-breakpoint--lg) { @@ -98,14 +80,6 @@ } } -.vf-footer__link { - @include inline-link( - $vf-link--color: $vf-footer-link--color, - $vf-link--hover-color: $vf-footer-link--hover-color, - $vf-link--visited-color: $vf-footer-link--visited-color - ); -} - .vf-footer__list--legal { grid-column: 1 / -1; @@ -227,3 +201,233 @@ grid-template-columns: repeat(1, 1fr); } } + +.vf-footer .vf-logo__image { + display: block; + height: auto; +} + +$vf-footer-partner-logo-width: 174px; +$vf-footer-partner-logo-height: 64px; +$vf-footer-partner-rule-width: 8px; + +.vf-footer__inner { + display: flex; + flex-direction: column; + gap: map-get($vf-spacing-map, vf-spacing--800); + grid-column: main; + margin: 0 auto; + max-width: $vf-layout--comfortable; + padding: 0; +} + +// Keep spacing consistent across the three logical rows. + +.vf-footer__partners { + border-top: $vf-footer-partner-rule-width solid var(--vf-color--green, #18974c); + padding-top: map-get($vf-spacing-map, vf-spacing--400); + padding-bottom: map-get($vf-spacing-map, vf-spacing--400); +} + +// Partner column/summary padding +.vf-footer__partners .vf-grid.vf-grid__col-4 > div:first-child, +.vf-footer__partners > div { + padding-left: map-get($vf-spacing-map, vf-spacing--400); +} + +// Main footer row padding +.vf-footer > .vf-grid.vf-grid__col-2 { + padding-bottom: map-get($vf-spacing-map, vf-spacing--800); +} + +// Legal section padding +.vf-footer__legal { + padding-bottom: map-get($vf-spacing-map, vf-spacing--800); + @include set-type(text-body--5, $custom-margin-bottom: 0); + + @media (max-width: 768px) { + justify-content: center; + text-align: center; + } +} + +.vf-footer__legal span { + color: var(--vf-color--grey--lightest, #fff); +} + +.vf-footer.vf-footer--without-rule { + border-top: 0; +} + +.vf-footer.vf-footer--without-rule::after { + display: none; +} + +// Heading styles with margins +.vf-footer h4 { + @include set-type(text-body--4, $custom-margin-bottom: map-get($vf-spacing-map, vf-spacing--400)); + color: var(--vf-color--grey--lightest, #fff); +} + +.vf-links__heading { + @include set-type(text-body--4, $custom-margin-bottom: map-get($vf-spacing-map, vf-spacing--400)); + color: var(--vf-color--grey--lightest, #fff); +} + +// Partner section text styles with margins +.vf-footer__partners h4 { + @include set-type(text-body--4, $custom-margin-bottom: map-get($vf-spacing-map, vf-spacing--400)); + color: var(--vf-color--grey--dark, #54585a); +} + +.vf-footer__partners p { + @include set-type(text-body--3, $custom-margin-bottom: map-get($vf-spacing-map, vf-spacing--200)); + color: var(--vf-color--grey--dark, #54585a); +} + +// List item margins +.vf-footer .vf-links__list { + padding: 0; + margin: 0; +} + +.vf-footer .vf-list__item { + margin-bottom: map-get($vf-spacing-map, vf-spacing--200); +} + +// Link styles in footer +.vf-footer a.vf-list__link { + @include set-type(text-body--2, $custom-margin-bottom: 0); + color: var(--vf-color--ui--white, #fff); +} + +.vf-footer__link { + @include inline-link( + $vf-link--color: $vf-footer-link--color, + $vf-link--hover-color: $vf-footer-link--hover-color, + $vf-link--visited-color: $vf-footer-link--visited-color + ); + @include set-type(text-body--5, $custom-margin-bottom: 0); + color: var(--vf-color--ui--white, #fff); +} + +// Contact details styles with margins +.vf-footer__contact p { + @include set-type(text-body--5, $custom-margin-bottom: map-get($vf-spacing-map, vf-spacing--200)); + color: var(--vf-color--grey--lightest, #fff); +} + +.vf-footer__contact a { + @include set-type(text-body--5, $custom-margin-bottom: 0); + color: var(--vf-color--ui--white, #fff); +} + +.vf-footer__notice { + @include set-type(text-body--3, $custom-margin-bottom: 0); + color: var(--vf-color--ui--white, #fff); + flex-grow: 4; + line-height: 1.2; + max-width: 45em; +} + +.vf-footer__legal a { + @include set-type(text-body--5, $custom-margin-bottom: 0); + color: var(--vf-color--ui--white, #fff); +} + +// Partner stat styles +.vf-footer__stat p { + margin: 0; +} + +.vf-footer .vf-footer__stat p:first-child { + @include set-type(text-heading--2, $custom-margin-bottom: 0); +} + +.vf-footer .vf-footer__stat p:last-child { + @include set-type(text-body--4, $custom-margin-bottom: 0); +} + +// Logo section margin +.vf-footer > .vf-grid > div:first-child { + margin-bottom: map-get($vf-spacing-map, vf-spacing--800); +} + +.vf-footer__logo-wrapper { + margin-bottom: map-get($vf-spacing-map, vf-spacing--800); +} + +.vf-footer__partners .vf-list__item { + margin-bottom: 0 !important; +} + +.vf-footer__partners .vf-list__item img { + width: $vf-footer-partner-logo-width !important; + height: $vf-footer-partner-logo-height !important; +} + +.vf-footer__social { + padding-top: map-get($vf-spacing-map, vf-spacing--800); +} + +.vf-footer__social-link { + text-decoration: none; + margin: 0 6px; + + @media (max-width: 768px) { + margin: 0 5px; + } +} +.vf-footer--light,.vf-u-background-color-ui--white{ + z-index: 1; +} +.vf-footer--light .vf-u-text-color--white { + color: var(--vf-color--ui--black, #000); +} + +.vf-footer--light .vf-u-text-color--grey--lightest { + color: var(--vf-color--grey--dark, #54585a); +} + +// Light theme text and link color overrides +.vf-footer--light h4 { + color: var(--vf-color--grey--dark, #54585a); +} + +.vf-footer--light .vf-links__heading { + color: var(--vf-color--grey--dark, #54585a); +} + +.vf-footer--light a.vf-list__link { + color: var(--vf-color--grey--dark, #54585a); +} + +.vf-footer--light .vf-footer__link { + color: var(--vf-color--ui--black, #000); +} + +.vf-footer--light .vf-footer__contact p { + color: var(--vf-color--grey--dark, #54585a); +} + +.vf-footer--light .vf-footer__contact a { + color: var(--vf-color--ui--black, #000); +} + +.vf-footer--light .vf-footer__notice { + color: var(--vf-color--ui--black, #000); +} + +.vf-footer--light .vf-footer__legal span { + color: var(--vf-color--grey--dark, #54585a); +} + +.vf-footer--light .vf-footer__legal a { + color: var(--vf-color--ui--black, #000); +} + +.vf-footer.vf-footer--light .vf-footer__link:hover, +.vf-footer__partners .vf-list__link, +.vf-footer__partners .vf-list__item:hover { + color: var(--vf-color--ui--black, #000) !important; +} \ No newline at end of file diff --git a/components/vf-minimal-footer/CHANGELOG.md b/components/vf-minimal-footer/CHANGELOG.md new file mode 100755 index 0000000000..14ee4a63f7 --- /dev/null +++ b/components/vf-minimal-footer/CHANGELOG.md @@ -0,0 +1,3 @@ +### 1.0.0-alpha.1 + +* Initial stable release diff --git a/components/vf-minimal-footer/README.md b/components/vf-minimal-footer/README.md new file mode 100755 index 0000000000..721ae36830 --- /dev/null +++ b/components/vf-minimal-footer/README.md @@ -0,0 +1,165 @@ +# Footer component + +[![npm version](https://badge.fury.io/js/%40visual-framework%2Fvf-minimal-footer.svg)](https://badge.fury.io/js/%40visual-framework%2Fvf-minimal-footer) + +## About + +The EMBL-EBI-minimal-footer provides a consistent approach to displaying our brand image, essential links and legal information at the bottom of our service pages. + +## Usage +### Description + +This footer is designed to display branding and essential content within the EMBL-EBI ecosystem without overwhelming the user experience. This approach ensures a clear and consistent representation of the EMBL-EBI identity across services and websites, and provides a structured pattern for communicating partnerships and collaborations. + +### When to use + +- Across EMBL-EBI platforms and organisational digital properties, particularly recommended for service pages within the ebi.ac.uk domain + +- Where the EBML-EBI branding, essential links and legal information are required + +- For task oriented pages such as payment pages or registration pages + +- Where there is a need to show collaboration with multiple partners + +### When not to use + +- In cases where the footer needs to reflect the service site's navigation + +- Where the social media channels are to be added + +For cases like this we recommend using the Modular variant which offers more flexibility. + +### Deciding what to use + +| Variant | Examples | Description | +| --- | --- | --- | +| [Modular](../vf-footer) | VF-footer | Use when footer sections need to be customised | +| EMBL-EBI Corporate Variant | [EMBL_EBI header-footer](../ebi-header-footer) | Use the EMBL-EBI corporate variant for organisational or self-contained experiences | +| | [Minimal](../vf-minimal-footer) | Use when only essential brand and legal information is needed | + +### Collaboration section variants + +The collaborations section provides standardised patterns for displaying varying levels of partnerships and collaborations. The display format adapts based on the number of collaborators. + +The Collaborations section renders its own top green border. Remove the footer's default top margin line to prevent duplication. + +Logos display (1 - 6 partners) + +When you have between 1 and 6 partners, display their logos horizontally across the section. + +- Uses a 6-column grid at desktop breakpoint (1154px+) + +- One logo per column + +- Maximum logo dimensions: 174px width and 64x height + +- Logos centred within their column + +- Scale down logos proportionally if they exceed maximum dimensions + +- For best image resolution, svg usage is recommended + +Partners links in columns (1 - 9 partners) + +When you have between 1 and 9 partners, you need to display their names as text links. + +- 3-column layout on desktop  + +- Partner names displayed as clickable links + +- Text aligned left within each column + +Categorised summary (10+ partners) + +When you have 10 or more partners, synthesise them into categories with summary numbers and a "See all collaborators" link. + +- Optional partnership statement describing the nature of collaborations + +- Summary categories displayed as numbers with labels (e.g., "35 Data partners", "4 Supporting funders") + +- "See all collaborators" link that directs to a dedicated page listing all partners + +- Placeholder text can be customisable + +### Choosing the right collaboration variant + +| Variant | Nº of partners | Usage | +| --- | --- | --- | +| Logo display | 1 - 6 | Provides strong visual recognition for each partner | +| Text links in columns | 1 - 9 | Maintains readability whilst accommodating more partners | +| Categorised summary | 10+ | Prevents footer from becoming overwhelming; directs users to dedicated page | + +### Usability and content guidance + +The content in the footer is designed to clearly describe the relationship between the services and EMBL-EBI. The footer has clear link labels and descriptions such as: "[Name of resource] is developed and maintained by EMBL-EBI, a world leader in biological data resources", for other use cases of descriptions, contact the Comms team via this email comms@ebi.ac.uk for support with appropriate wording. + +The content in the minimal footer variant is standardised to ensure consistency across our services. + +| Element | Required | Notes | +| --- | --- | --- | +| EMBL-EBI logo | Yes | The logo should not be altered on the services page | +| Description | Yes | The content should reflect the relationship between the service and EMBL-EBI | +| Utility & legal links | Yes | Bottom bar with Terms of use, EMBL-EBI affiliation and copyright. These links should be retained. | +| Collaborators | No | This can be added for acknowledgment of collaborators | + +### Terms of Use (ToU) + +Guidelines for domains requiring both Organisation-wide and Service-specific Terms + +When a domain requires both organisation-wide Terms of Use and service-specific Terms of Use, teams should create a single dedicated page that clearly presents both sets of terms together. This consolidated approach ensures users can easily understand which terms apply to their specific use case while maintaining a single, clear ToU link in the footer. This prevents confusion from multiple links with similar names and provides a better user experience. + +Cookie banner pattern + +Avoid including ToU in cookie banners. Terms of Use should remain permanently visible in the footer rather than in a dismissible cookie consent banner. Cookie banners are temporary and can be dismissed by users, removing access to critical legal information. By keeping ToU in the footer, users can always access this information whenever needed, regardless of their cookie consent choices. + +### Themes + +The footer is available in two colour schemes: light and dark, to establish clear visual distinction from page content. + +Apply the light scheme when the page background uses colour or tone, and the dark scheme when the background is white or near-white. This intentional contrast ensures users can clearly identify where the main content concludes and the footer begins. + +### Responsiveness + +The elements wrap across the tablet and mobile breaking points while ensuring spacing, readability and target touch size are optimised for accessibility and ease of use. + +### Accessibility + +This component targets WCAG 2.1 AA accessibility standard. + +- Links provide direct location description [Manual testing required]: Ensure link text is descriptive and not ambiguous. WCAG A 2.4.4 Link purpose (in context) + +- Keyboard navigation: All links and interactive elements are keyboard accessible + +- Focus indicators: Clear visual focus states meet 3:1 contrast requirements + +- Touch targets: All clickable elements meet the minimum 44×44 pixel touch target size on mobile and tablet + +- Colour contrast: Text and link colours have been tested against both light and dark backgrounds + +- Screen readers: Semantic HTML and ARIA labels ensure footer content is properly announced + +- Responsive design: Footer adapts appropriately across mobile (600px), tablet (768px) and desktop (1154px) breakpoints + +## Install + +This component is distributed with npm. After [installing npm](https://www.npmjs.com/get-npm), you can install the `vf-minimal-footer` with this command. + +``` +$ yarn add --dev @visual-framework/vf-minimal-footer +``` + +### Sass/CSS + +The source files included are written in [Sass](http://sass-lang.com)(`scss`). You can point your Sass `include-path` at your `node_modules` directory and import it like this. + +``` +@import "@visual-framework/vf-minimal-footer/index.scss"; +``` + +Make sure you import Sass requirements along with the modules. You can use a [project boilerplate](https://stable.visual-framework.dev/building/) or the [`vf-sass-starter`](https://stable.visual-framework.dev/components/vf-sass-starter/) + +## Help + +- [Read the Visual Framework troubleshooting](https://stable.visual-framework.dev/troubleshooting/) +- [Open a ticket](https://github.com/visual-framework/vf-core/issues) +- [Chat on Slack](https://join.slack.com/t/visual-framework/shared_invite/enQtNDAxNzY0NDg4NTY0LWFhMjEwNGY3ZTk3NWYxNWVjOWQ1ZWE4YjViZmY1YjBkMDQxMTNlNjQ0N2ZiMTQ1ZTZiMGM4NjU5Y2E0MjM3ZGQ) diff --git a/components/vf-minimal-footer/assets/embl-ebi-rgb-all-white.png b/components/vf-minimal-footer/assets/embl-ebi-rgb-all-white.png new file mode 100644 index 0000000000..f257e59461 Binary files /dev/null and b/components/vf-minimal-footer/assets/embl-ebi-rgb-all-white.png differ diff --git a/components/vf-minimal-footer/assets/embl-ebi-rgb-full-colour.svg b/components/vf-minimal-footer/assets/embl-ebi-rgb-full-colour.svg new file mode 100644 index 0000000000..2074da77d2 --- /dev/null +++ b/components/vf-minimal-footer/assets/embl-ebi-rgb-full-colour.svg @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/vf-minimal-footer/assets/landscape-placeholder.svg b/components/vf-minimal-footer/assets/landscape-placeholder.svg new file mode 100644 index 0000000000..faea08cd58 --- /dev/null +++ b/components/vf-minimal-footer/assets/landscape-placeholder.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/components/vf-minimal-footer/index.scss b/components/vf-minimal-footer/index.scss new file mode 100755 index 0000000000..fe256ed31a --- /dev/null +++ b/components/vf-minimal-footer/index.scss @@ -0,0 +1,11 @@ +// setup files required + +// sass-lint:disable clean-import-paths +@import 'vf-global-variables'; +@import 'vf-variables'; +@import 'vf-functions'; +@import 'vf-mixins'; + +// component specific styles + +@import 'vf-minimal-footer.scss'; diff --git a/components/vf-minimal-footer/package.json b/components/vf-minimal-footer/package.json new file mode 100755 index 0000000000..0f66263fdd --- /dev/null +++ b/components/vf-minimal-footer/package.json @@ -0,0 +1,23 @@ +{ + "version": "1.0.0-alpha.1", + "name": "@visual-framework/vf-minimal-footer", + "description": "vf-minimal-footer component", + "homepage": "https://stable.visual-framework.dev/", + "author": "VF", + "license": "Apache 2.0", + "style": "build/vf-minimal-footer.css", + "main": "build/index.js", + "test": "echo \"Error: no test specified\" && exit 1", + "publishConfig": { + "access": "public" + }, + "repo": "https://github.com/visual-framework/vf-core/tree/master/components/elements/vf-minimal-footer", + "bugs": { + "url": "https://github.com/visual-framework/vf-core/issues" + }, + "keywords": [ + "fractal", + "component" + ], + "gitHead": "13228e9ef51f1584c696e9d7db282fa786318b88" +} diff --git a/components/vf-minimal-footer/vf-minimal-footer.config.yml b/components/vf-minimal-footer/vf-minimal-footer.config.yml new file mode 100755 index 0000000000..92ed0d63ab --- /dev/null +++ b/components/vf-minimal-footer/vf-minimal-footer.config.yml @@ -0,0 +1,34 @@ +title: Minimal Footer +label: Minimal Footer +preview: '@preview--nogrid' +status: live +context: + footer__theme: 'dark' + component-type: container + hide-from-sitemenu: true + partner__variant: null + +variants: + - name: Dark footer theme + context: + footer__theme: 'dark' + + - name: Light footer theme + context: + footer__theme: 'light' + + - name: Logo display + context: + footer__theme: 'dark' + partner__variant: logos + + - name: Partners links in columns + context: + footer__theme: 'dark' + partner__variant: columns + + - name: Categorised summary + context: + footer__theme: 'dark' + partner__variant: summary + diff --git a/components/vf-minimal-footer/vf-minimal-footer.njk b/components/vf-minimal-footer/vf-minimal-footer.njk new file mode 100755 index 0000000000..5ad30da98e --- /dev/null +++ b/components/vf-minimal-footer/vf-minimal-footer.njk @@ -0,0 +1,114 @@ +{# vf-minimal-footer #} +{% set _theme = footer__theme if footer__theme else 'dark' %} +{% set _isLight = true if _theme == 'light' else false %} +{% set _logoSrc = '../../assets/vf-minimal-footer/assets/embl-ebi-rgb-full-colour.svg' if _isLight else '../../assets/vf-minimal-footer/assets/embl-ebi-rgb-all-white.png' %} + +{% if partner__variant %} + +{% endif %} + + diff --git a/components/vf-minimal-footer/vf-minimal-footer.scss b/components/vf-minimal-footer/vf-minimal-footer.scss new file mode 100644 index 0000000000..8740fa8cdd --- /dev/null +++ b/components/vf-minimal-footer/vf-minimal-footer.scss @@ -0,0 +1 @@ +@import "../vf-footer/vf-footer.scss"; diff --git a/tools/vf-component-library/src/site/_includes/layouts/components.njk b/tools/vf-component-library/src/site/_includes/layouts/components.njk index 4d485e27be..1e227ec7bd 100644 --- a/tools/vf-component-library/src/site/_includes/layouts/components.njk +++ b/tools/vf-component-library/src/site/_includes/layouts/components.njk @@ -200,6 +200,7 @@ templateEngineOverride: njk {# ---- #} {% if variants %} + {% if component.baseHandle != 'footer' %} {% render '@vf-heading', { "type": 1, "heading": "Variants", @@ -342,6 +343,7 @@ import { {{ component.baseHandle | camelize(true) | replace("-", "") }} } from " {% endif %} {% endfor -%} + {% endif %} {# Examples #} {% render '@vf-heading', { @@ -401,6 +403,7 @@ import { {{ component.baseHandle | camelize(true) | replace("-", "") }} } from " {% markdown %} {% if component.notes %} + {% if component.baseHandle != 'footer' %} {% set readmeInstallation = component.notes | string | stringBetween("## Install", "\n## ") %} {% if readmeInstallation %} @@ -422,6 +425,7 @@ import { {{ component.baseHandle | camelize(true) | replace("-", "") }} } from " {% endmarkdown %} {% endif %} + {% endif %} {% else %} {% markdown %} @@ -431,6 +435,7 @@ import { {{ component.baseHandle | camelize(true) | replace("-", "") }} } from " {% endmarkdown %} {% endif %} + {% if component.baseHandle != 'footer' %} ### Assets - [Nunjucks template]({{ ('/assets/' + component.baseHandle + '/' + component.baseHandle + '.njk') | url }}) @@ -439,6 +444,7 @@ import { {{ component.baseHandle | camelize(true) | replace("-", "") }} } from " {%- for asset in component.resources.assets %} - [{{asset.base}}]({{ ('/assets/' + asset.relPath ) | url }}) {%- endfor %} + {% endif %} {% endmarkdown %} {% endif %}