Skip to content
This repository has been archived by the owner on Aug 13, 2023. It is now read-only.

Add scripLink prop to render ScriptLink component #2474

Merged
15 commits merged into from
Oct 29, 2019
Merged
Show file tree
Hide file tree
Changes from 7 commits
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
1 change: 1 addition & 0 deletions packages/components/psammead-brand/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<!-- prettier-ignore -->
| Version | Description |
| ------- | ----------- |
| 5.1.0-alpha.1 | [PR#2474](https://github.com/bbc/psammead/pull/2474) Add scriptLink prop to render `ScriptLink` used for linking to service variants |
| 5.0.9 | [PR#2477](https://github.com/bbc/psammead/pull/2477) Talos - Bump Dependencies - @bbc/psammead-styles |
| 5.0.8 | [PR#2440](https://github.com/bbc/psammead/pull/2440) Talos - Bump Dependencies - @bbc/psammead-visually-hidden-text, @bbc/psammead-styles |
| 5.0.7 | [PR#2404](https://github.com/bbc/psammead/pull/2404) replace inputProvider and dirDecorator with withServicesInput |
Expand Down
37 changes: 30 additions & 7 deletions packages/components/psammead-brand/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# ⛔️ This is an alpha component ⛔️

This component is currently tagged as alpha and is not suitable for production use. Following the passing of an accessibility review this component will be marked as ready for production and the alpha tag removed.

# psammead-brand - [![Known Vulnerabilities](https://snyk.io/test/github/bbc/psammead/badge.svg?targetFile=packages%2Fcomponents%2Fpsammead-brand%2Fpackage.json)](https://snyk.io/test/github/bbc/psammead?targetFile=packages%2Fcomponents%2Fpsammead-brand%2Fpackage.json) [![Dependency Status](https://david-dm.org/bbc/psammead.svg?path=packages/components/psammead-brand)](https://david-dm.org/bbc/psammead?path=packages/components/psammead-brand) [![peerDependencies Status](https://david-dm.org/bbc/psammead/peer-status.svg?path=packages/components/psammead-brand)](https://david-dm.org/bbc/psammead?path=packages/components/psammead-brand&type=peer) [![Storybook](https://raw.githubusercontent.com/storybooks/brand/master/badge/badge-storybook.svg?sanitize=true)](https://bbc.github.io/psammead/?path=/story/brand--default) [![GitHub license](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/bbc/psammead/blob/latest/LICENSE) [![npm version](https://img.shields.io/npm/v/@bbc/psammead-brand.svg)](https://www.npmjs.com/package/@bbc/psammead-brand) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/bbc/psammead/blob/latest/CONTRIBUTING.md)

## Description
Expand All @@ -6,20 +10,22 @@ The `Brand` component provides the BBC service logo (as SVG), nested inside a st

`Brand` takes a `product`, `svgHeight`, `minWidth`, `maxWidth`, `url`, `serviceLocalisedName`, `backgroundColour`, `logoColour` and `svg` as props.

The `product` is passed to a [VisuallyHiddenText](https://github.com/bbc/psammead/tree/latest/packages/components/VisuallyHiddenText) component, nested inside Brand.
The `product` is passed to a [VisuallyHiddenText](https://github.com/bbc/psammead/tree/latest/packages/components/psammead-visually-hidden-text) component, nested inside Brand.

The `serviceLocalisedName` is an optional prop referring to the local name of a service eg `Yoruba`. It is also passed to [VisuallyHiddenText](https://github.com/bbc/psammead/tree/latest/packages/components/VisuallyHiddenText) inside the Brand component.
The `serviceLocalisedName` is an optional prop referring to the local name of a service eg `Yoruba`. It is also passed to [VisuallyHiddenText](https://github.com/bbc/psammead/tree/latest/packages/components/psammead-visually-hidden-text) inside the Brand component.

The `svg` prop must contain a `group`, `viewbox` values and a `ratio`, which is used within an `svg` element. Examples of the `svg` object can be found in [@bbc/psammead-assets](https://github.com/bbc/psammead/blob/latest/packages/utilities/psammead-assets/README.md#service-svgs).

The `minWidth` and `maxWidth` values are required to allow the ability for the `svg` element to dynamically scale as the viewport becomes a very small size EG: feature phones.

The `svgHeight` value acts as a placeholder for the `svg` element meaning the overall banner height does not change with the dynamic scaling, also the `height` allows the contents of the `svg` element to remain vertically centred within the banner at all times.

The `backgroundColour` is the background colour and `logoColour` is the colour of the SVG and the underline when hovering/focusing on the brand.
The `backgroundColour` is the background colour and `logoColour` is the colour of the SVG and the underline when hovering/focusing on the brand.

The `url` value is the link that points to the frontpage of the service associated with the `svg`.

The `scriptLink` can be used to render [ScriptLink](https://github.com/bbc/psammead/tree/latest/packages/components/psammead-script-link) component which is a link to the service variant.

## Installation

`npm install @bbc/psammead-brand`
Expand All @@ -34,24 +40,39 @@ The `url` value is the link that points to the frontpage of the service associat
| minWidth | Number | yes | N/A | `240` |
| maxWidth | Number | yes | N/A | `380` |
| svg | Object | yes | N/A | { group: `(<g fillrule="evenodd"><path d="M84.32" /></g>)`, viewbox: { height: 24, width: 167.95 }, ratio: 6.9979 } |
| backgroundColour | string | yes | N/A | `${C_POSTBOX}` or relevant string hex code |
| logoColour | string | yes | N/A | `${C_WHITE}` or relevant string hex code |
| backgroundColour | String | yes | N/A | `${C_POSTBOX}` or relevant string hex code |
| logoColour | String | yes | N/A | `${C_WHITE}` or relevant string hex code |
| url | String | no | N/A | `https://www.bbc.co.uk/news` |
| serviceLocalisedName | String | no | N/A | `'Yoruba'` |
| borderTop | bool | no | `false` | `true` |
| borderBottom | bool | no | `false` | `true` |
| borderTop | Boolean | no | `false` | `true` |
| borderBottom | Boolean | no | `false` | `true` |
| scriptLink | Node | no | `null` | `<ScriptLink service='news' script={latin} href='https://www.bbc.com/serbian/lat'> Lat </ScriptLink>` |
| dir | string | No | `'ltr' | One of `'rtl'`, `'ltr' |

## Usage

The typical use-case of this component is at the top of pages in a [`header` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/header). When this is done it is recommend that the component is wrapped in a [`banner` role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Banner_role). However, a `header` with a `banner` role should only appear once on a page.

When using `Brand` in the header, you should ensure that `borderBottom` prop is set to true. Similarly, when using brand on the footer you should set `borderTop` to true. This ensures when in High Contrast Mode on PC and when the user changes colour preferences in FireFox that the top/bottom of the `Brand` component is visible.

`ScriptLink` component should be passed to `scriptLink` only when linking to a service variant.

```jsx
import Brand from '@bbc/psammead-brand';
import { igbo } from '@bbc/psammead-assets/svgs';
import ScriptLink from '@bbc/psammead-script-link';
import { C_POSTBOX, C_WHITE } from '@bbc/psammead-styles/colours';

const scriptLink = (
<ScriptLink
service="news"
script={latin}
href="https://www.bbc.com/serbian/lat"
>
Lat
</ScriptLink>
);

const Header = (product, serviceName) => (
<header role="banner">
<Brand
Expand All @@ -65,6 +86,8 @@ const Header = (product, serviceName) => (
backgroundColour={backgroundColour}
logoColour={logoColour}
borderBottom
scriptLink={scriptLink}
dir="ltr"
/>
</header>
);
Expand Down
12 changes: 11 additions & 1 deletion packages/components/psammead-brand/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions packages/components/psammead-brand/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@bbc/psammead-brand",
"version": "5.0.9",
"version": "5.1.0-alpha.1",
"main": "dist/index.js",
"module": "esm/index.js",
"sideEffects": false,
Expand All @@ -23,6 +23,7 @@
"@bbc/psammead-visually-hidden-text": "^1.2.3"
},
"devDependencies": {
"@bbc/psammead-script-link": "^1.0.0-alpha.4",
"@bbc/psammead-styles": "^4.0.4"
},
"peerDependencies": {
Expand All @@ -33,5 +34,8 @@
"bbc",
"brand",
"logo"
]
],
"publishConfig": {
"tag": "alpha"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ exports[`Brand should render correctly with link not provided 1`] = `
}

.c1 {
position: relative;
max-width: 80rem;
margin: 0 auto;
}
Expand Down Expand Up @@ -51,6 +52,12 @@ exports[`Brand should render correctly with link not provided 1`] = `
}
}

@media (max-width:14.9375rem) {
.c0 {
min-height: 6.5rem;
}
}

@media (min-width:25rem) {
.c2 {
padding-top: 1.75rem;
Expand Down Expand Up @@ -116,6 +123,7 @@ exports[`Brand should render correctly with link provided 1`] = `
}

.c1 {
position: relative;
max-width: 80rem;
margin: 0 auto;
}
Expand Down Expand Up @@ -160,6 +168,12 @@ exports[`Brand should render correctly with link provided 1`] = `
}
}

@media (max-width:14.9375rem) {
.c0 {
min-height: 6.5rem;
}
}

@media (min-width:25rem) {
.c4 {
padding-top: 1.75rem;
Expand Down Expand Up @@ -230,6 +244,7 @@ exports[`Brand should render correctly with no service Localised Name 1`] = `
}

.c1 {
position: relative;
max-width: 80rem;
margin: 0 auto;
}
Expand Down Expand Up @@ -267,6 +282,12 @@ exports[`Brand should render correctly with no service Localised Name 1`] = `
}
}

@media (max-width:14.9375rem) {
.c0 {
min-height: 6.5rem;
}
}

@media (min-width:25rem) {
.c2 {
padding-top: 1.75rem;
Expand Down Expand Up @@ -325,6 +346,7 @@ exports[`Brand should render correctly with transparent borders 1`] = `
}

.c1 {
position: relative;
max-width: 80rem;
margin: 0 auto;
}
Expand Down Expand Up @@ -364,6 +386,12 @@ exports[`Brand should render correctly with transparent borders 1`] = `
}
}

@media (max-width:14.9375rem) {
.c0 {
min-height: 6.5rem;
}
}

@media (min-width:25rem) {
.c2 {
padding-top: 1.75rem;
Expand Down
44 changes: 43 additions & 1 deletion packages/components/psammead-brand/src/index.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import React from 'react';
import styled from 'styled-components';
import { string, number, node, shape, bool } from 'prop-types';
import { string, number, node, shape, bool, oneOf } from 'prop-types';
import VisuallyHiddenText from '@bbc/psammead-visually-hidden-text';
import {
GEL_GROUP_2_SCREEN_WIDTH_MIN,
GEL_GROUP_5_SCREEN_WIDTH_MIN,
GEL_GROUP_0_SCREEN_WIDTH_MAX,
GEL_GROUP_1_SCREEN_WIDTH_MAX,
} from '@bbc/gel-foundations/breakpoints';
import {
GEL_SPACING_HLF,
Expand All @@ -24,6 +26,7 @@ const conditionallyRenderHeight = (svgHeight, padding) =>
const TRANSPARENT_BORDER = `0.0625rem solid transparent`;

const SvgWrapper = styled.div`
position: relative;
max-width: ${GEL_GROUP_5_SCREEN_WIDTH_MIN};
margin: 0 auto;
`;
Expand All @@ -40,6 +43,11 @@ const Banner = styled.div`
conditionallyRenderHeight(svgHeight, PADDING_AROUND_SVG_ABOVE_400PX)}
padding: 0 ${GEL_SPACING_DBL};
}

@media (max-width: ${GEL_GROUP_0_SCREEN_WIDTH_MAX}) {
min-height: ${({ svgHeight }) => svgHeight / 16 + 5}rem;
}

border-top: ${({ borderTop }) => borderTop && TRANSPARENT_BORDER};
border-bottom: ${({ borderBottom }) => borderBottom && TRANSPARENT_BORDER};
`;
Expand Down Expand Up @@ -164,6 +172,30 @@ StyledBrand.defaultProps = {
serviceLocalisedName: null,
};

const ScriptLinkWrapper = styled.div`
display: inline-block;
@media (max-width: ${GEL_GROUP_0_SCREEN_WIDTH_MAX}) {
padding-top: 0;
position: relative;
right: 0;
display: block;
}

@media (max-width: ${GEL_GROUP_1_SCREEN_WIDTH_MAX}) {
top: calc(50% - 1.25rem);
}
position: absolute;
${({ dir }) => (dir === 'ltr' ? 'right: 0' : 'left: 0')};
top: calc(50% - 1.5rem);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The top calculation is wrong when the screen is small, making the link to go outside the banner when it should stay in it.

brand-wrong

brand-right

Instead of making it absolute and calculate the top position, an alternative would be to add a new div to wrap both, Brand and Script Link, and use flex to align the items vertically and put them on each side. And then you wouldn't need ScriptLinkWrapper and SvgWrapper, just to apply a couple of tweaks to the Banner height and padding. Up to you :)

const StyledWrapper = styled.div`
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  max-width: ${GEL_GROUP_5_SCREEN_WIDTH_MIN};
  margin: 0 auto;
`;
  <Banner
      svgHeight={svgHeight}
      borderTop={borderTop}
      borderBottom={borderBottom}
      backgroundColour={backgroundColour}
      logoColour={logoColour}
      {...rest}
    >
      <StyledWrapper>
        {url ? (
          <StyledLink href={url} maxWidth={maxWidth} minWidth={minWidth}>
            <StyledBrand {...props} />
          </StyledLink>
        ) : (
          <StyledBrand {...props} />
        )}
        {scriptLinkComponent}
      </StyledWrapper>
    </Banner>

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DenisHdz Good point. Done 😎

`;

const renderScriptLink = (scriptLink, dir, svgHeight) =>
scriptLink && (
<ScriptLinkWrapper dir={dir} svgHeight={svgHeight}>
{scriptLink}
</ScriptLinkWrapper>
);

const Brand = props => {
const {
svgHeight,
Expand All @@ -174,9 +206,13 @@ const Brand = props => {
borderBottom,
backgroundColour,
logoColour,
scriptLink,
dir,
...rest
} = props;

const scriptLinkComponent = renderScriptLink(scriptLink, dir, svgHeight);

return (
<Banner
svgHeight={svgHeight}
Expand All @@ -191,10 +227,12 @@ const Brand = props => {
<StyledLink href={url} maxWidth={maxWidth} minWidth={minWidth}>
<StyledBrand {...props} />
</StyledLink>
{scriptLinkComponent}
</SvgWrapper>
) : (
<SvgWrapper>
<StyledBrand {...props} />
{scriptLinkComponent}
</SvgWrapper>
)}
</Banner>
Expand All @@ -206,6 +244,8 @@ Brand.defaultProps = {
serviceLocalisedName: null,
borderTop: false,
borderBottom: false,
scriptLink: null,
dir: 'ltr',
};

Brand.propTypes = {
Expand All @@ -214,6 +254,8 @@ Brand.propTypes = {
serviceLocalisedName: string,
borderTop: bool,
borderBottom: bool,
scriptLink: node,
dir: oneOf(['rtl', 'ltr']),
};

export default Brand;
47 changes: 47 additions & 0 deletions packages/components/psammead-brand/src/index.stories.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { storiesOf } from '@storybook/react';
import * as svgs from '@bbc/psammead-assets/svgs';
import { C_POSTBOX, C_WHITE } from '@bbc/psammead-styles/colours';
import { withServicesKnob } from '@bbc/psammead-storybook-helpers';
import ScriptLink from '@bbc/psammead-script-link';
import notes from '../README.md';
import Brand from './index';

Expand Down Expand Up @@ -117,4 +118,50 @@ storiesOf('Components|Brand', module)
);
},
{ notes },
)
.add(
'with script link',
({ service, dir, script }) => {
const scriptLink = (
<ScriptLink
script={script}
service={service}
href="https://www.bbc.com/serbian/lat"
>
Lat
</ScriptLink>
);

const {
productInput,
serviceLocalisedNameInput,
svgHeightInput,
minWidthInput,
maxWidthInput,
svgChoice,
borderBottom,
borderTop,
backgroundColour,
logoColour,
} = inputs();

return (
<Brand
dir={dir}
product={productInput}
serviceLocalisedName={serviceLocalisedNameInput}
svgHeight={svgHeightInput}
minWidth={minWidthInput}
maxWidth={maxWidthInput}
svg={svgs[svgChoice]}
url="https://www.bbc.com/news"
borderBottom={borderBottom}
borderTop={borderTop}
backgroundColour={backgroundColour}
logoColour={logoColour}
scriptLink={scriptLink}
/>
);
},
{ notes },
);
Loading