-
Notifications
You must be signed in to change notification settings - Fork 6
Ent 2784 pro bar #1191
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Ent 2784 pro bar #1191
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
1beced3
chore: add codeowner for new pro bar
phelipemaia 2018718
feat: add pro header coving to layout
phelipemaia f457564
feat: add Pro Bar to layout
phelipemaia 094dccd
feat: Pro coving animation based on transitionend event rather than t…
phelipemaia eed007a
fix: remove unnecessary checks when updating coving content
phelipemaia 19c8d48
fix: improve readability of coving animation
phelipemaia 2e74218
fix: avoid uppercase on brand placeholder due to accessibility
phelipemaia b7a0649
feat: improve coving styling to use padding-block border-block
phelipemaia 940bc8b
fix: fix fetchLicenceInfo to make request against pro-navigation
phelipemaia File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
169 changes: 169 additions & 0 deletions
169
packages/dotcom-ui-layout/src/components/professional/headerCoving.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,169 @@ | ||
| /** | ||
| * Track a view event for a given DOM selector by dispatching an `oTracking.event`. | ||
| * | ||
| * @param {Object} [options] - Optional configuration. | ||
| * @param {string} [options.selector] - CSS selector for the element to track. | ||
| * @returns {void} | ||
| */ | ||
| const trackBarView = (options) => { | ||
| const selector = options && options.selector | ||
| const elementToTrack = document.querySelector(selector) | ||
| if (!elementToTrack) { | ||
| return | ||
| } | ||
|
|
||
| const eventData = { | ||
| action: 'view', | ||
| category: 'component', | ||
| className: elementToTrack.className, | ||
| url: window.document.location.href || null, | ||
| nodeName: elementToTrack.nodeName, | ||
| component_name: 'pro-bar' | ||
| } | ||
|
|
||
| document.body.dispatchEvent(new CustomEvent('oTracking.event', { detail: eventData, bubbles: true })) | ||
| } | ||
|
|
||
| /** | ||
| * Update the organisation title shown in the coving element. | ||
| * | ||
| * Fetches licence information from the provided proNavigationApi URL and updates | ||
| * the organisation name in the coving element. Emits tracking events on error. | ||
| * | ||
| * @param {Object} options - Configuration options. | ||
| * @param {string} options.proNavigationApi - URL to fetch licence info from. | ||
| * @returns {Promise<void>} | ||
| */ | ||
| const updateTitle = async (options) => { | ||
| if (!isDesktopOrTabletView()) { | ||
| return | ||
| } | ||
| const { proNavigationApi } = options | ||
|
|
||
| const coving = document.querySelector(`.n-layout__pro-coving`) | ||
| const textContainer = document.querySelector('.n-layout__pro-coving-text') | ||
| if (!coving || !textContainer) { | ||
| return | ||
| } | ||
|
|
||
| try { | ||
| const licenceInfo = await fetchLicenceInfo(proNavigationApi) | ||
|
|
||
| if (!licenceInfo || !licenceInfo.organisationName) { | ||
| return | ||
| } | ||
|
|
||
| if (licenceInfo.organisationName && licenceInfo.organisationName.length < 51) { | ||
| textContainer.classList.add('is-fading-out') | ||
| textContainer.addEventListener('transitionend', () => { | ||
| updateOrganisationName(coving, licenceInfo.organisationName) | ||
| textContainer.classList.remove('is-fading-out') | ||
| textContainer.classList.add('is-fading-in') | ||
|
|
||
| requestAnimationFrame(() => { | ||
| textContainer.classList.remove('is-fading-in') | ||
| }) | ||
| }, { once: true }) | ||
| } | ||
| } catch (error) { | ||
| const eventData = { | ||
| action: 'fetch', | ||
| category: 'error', | ||
| component_name: 'pro-bar', | ||
| errorMessage: error.message | ||
| } | ||
| document.body.dispatchEvent(new CustomEvent('oTracking.event', { detail: eventData, bubbles: true })) | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Fetch licence information from the given URL. | ||
| * | ||
| * Uses fetch with credentials included. Throws an Error if the response is not ok. | ||
| * | ||
| * @param {string} url - The API endpoint to fetch licence info from. | ||
| * @returns {Promise<Object>} Resolves with the parsed JSON response. | ||
| * @throws {Error} If the network response is not ok. | ||
| */ | ||
| const fetchLicenceInfo = async (url) => { | ||
| const response = await fetch(url, { credentials: 'include' }) | ||
| if (!response.ok) { | ||
| throw new Error(`Error during licence info fetch! Status: ${response.status}`) | ||
| } | ||
| return response.json() | ||
| } | ||
|
|
||
| /** | ||
| * Update the organisation name within the coving element. | ||
| * | ||
| * @param {Element} covingEl - The coving DOM element that contains the organisation name element. | ||
| * @param {string} organisationName - The organisation name to display. | ||
| * @returns {void} | ||
| */ | ||
| const updateOrganisationName = (covingEl, organisationName) => { | ||
| if (!covingEl || !organisationName) { | ||
| return | ||
| } | ||
|
|
||
| const organisationNameEl = covingEl.querySelector('.n-layout__pro-coving-organisation') | ||
| if (organisationNameEl) { | ||
| organisationNameEl.textContent = organisationName | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Determine if the current device is a desktop or tablet. | ||
| * | ||
| * Checks the user agent to identify mobile devices. Uses the modern `navigator.userAgentData` API | ||
| * if available, otherwise falls back to parsing `navigator.userAgent`. Returns `true` for desktop | ||
| * and tablet devices, `false` for mobile phones. | ||
| * | ||
| * @returns {boolean} `true` if the device is desktop or tablet, `false` if mobile. | ||
| */ | ||
| function isDesktopOrTabletView() { | ||
| if (navigator.userAgentData && navigator.userAgentData.mobile) { | ||
| return !navigator.userAgentData.mobile | ||
| } | ||
|
|
||
| const ua = navigator.userAgent.toLowerCase() | ||
|
|
||
| if (ua.includes('ipad') || (ua.includes('macintosh') && 'ontouchend' in window)) { | ||
| return true | ||
| } | ||
|
|
||
| if (ua.includes('iphone') || ua.includes('ipod')) { | ||
| return false | ||
| } | ||
|
|
||
| if (ua.includes('android') && ua.includes('mobile')) { | ||
| return false | ||
| } | ||
|
|
||
| if ( | ||
| ua.includes('windows phone') || | ||
| ua.includes('blackberry') || | ||
| ua.includes('bb10') || | ||
| ua.includes('opera mini') | ||
| ) { | ||
| return false | ||
| } | ||
|
|
||
| return true | ||
| } | ||
|
|
||
| /** | ||
| * Initialise the ProBar component: track view and update title. | ||
| * | ||
| * @returns {void} | ||
| */ | ||
| const init = () => { | ||
| trackBarView({ selector: '.n-layout__pro-coving' }) | ||
|
|
||
| updateTitle({ | ||
| proNavigationApi: 'https://pro-navigation.ft.com/api/licence/info' | ||
| }) | ||
| } | ||
|
|
||
| export const ProBar = { | ||
| init | ||
| } |
44 changes: 44 additions & 0 deletions
44
packages/dotcom-ui-layout/src/components/professional/headerCoving.scss
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| @import '@financial-times/o3-foundation/css/professional.css'; | ||
|
|
||
| .n-layout__pro-coving { | ||
| display: flex; | ||
| width: 100%; | ||
| background-color: var(--o3-color-palette-mint); | ||
| padding-block: var(--o3-spacing-4xs); | ||
| justify-content: center; | ||
| border-block: 1px solid rgba(0, 0, 0, 0.20); | ||
| } | ||
|
|
||
| .n-layout__pro-coving-text { | ||
| opacity: 1; | ||
| transition: opacity 0.5s ease; | ||
|
|
||
| font-size: var(--o3-type-label-font-size); | ||
| font-weight: var(--o3-font-weight-medium); | ||
| font-family: var(--o3-font-family-metric); | ||
| color: var(--o3-color-palette-slate); | ||
| } | ||
|
|
||
| .n-layout__pro-coving-text.is-fading-out { | ||
| opacity: 0; | ||
| } | ||
|
|
||
| .n-layout__pro-coving-text.is-fading-in { | ||
| opacity: 1; | ||
| } | ||
|
|
||
| .n-layout__pro-coving-brand { | ||
| text-transform: uppercase; | ||
| } | ||
|
|
||
| @media (prefers-reduced-motion: reduce) { | ||
| .n-layout__pro-coving-text { | ||
| transition: none; | ||
| } | ||
| } | ||
|
|
||
| .n-layout__pro-coving-organisation:not(:empty)::before { | ||
| content: "|"; | ||
| padding-inline: var(--o3-spacing-3xs); | ||
| color: var(--o3-color-palette-slate); | ||
| } | ||
12 changes: 12 additions & 0 deletions
12
packages/dotcom-ui-layout/src/components/professional/headerCoving.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| import React from 'react' | ||
|
|
||
| export const HeaderCoving = () => { | ||
| return ( | ||
| <div data-o3-brand="professional" className={`n-layout__pro-coving`}> | ||
| <div className={`n-layout__pro-coving-text`}> | ||
| <span className={`n-layout__pro-coving-brand`}>FT Professional</span> | ||
| <span className={`n-layout__pro-coving-organisation`}></span> | ||
| </div> | ||
| </div> | ||
| ) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thought: it would be good to get this (and the
slateforeground below) added too3-foundationas use case tokens (e.g.--o3-color-use-case-coving-background/foreground)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's a good idea.. however, I will add that to the professional brand only even though the header coving is a layout element now..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@apaleslimghost is this a use case value you see being used in FT Pink also?