npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@bbc/psammead-story-promo

v8.0.38

Published

A story promo for use on index pages

Downloads

871

Readme

psammead-story-promo - Known Vulnerabilities Dependency Status peerDependencies Status Storybook GitHub license npm version PRs Welcome

Description

The StoryPromo component is designed to be used on 'index' pages, which are pages that link to other articles/stories. This info can be any collection of nodes, however typically these would be a headline, text summary and timestamp.

Exports

/index-alsos - components for links to stories that are related to the top story.

Installation

npm install @bbc/psammead-story-promo

StoryPromo Props

| Argument | Type | Required | Default | Example | | -------- | ------ | -------- | ------- | -------------- | | image | node | no | Null | <img> | | info | node | yes | N/A | <h2>Title</h2> | | mediaIndicator | node | no | null | <MediaIndicator duration="2:15" datetime="PT2M15S" offscreenText="Video 2 minutes 15 seconds" /> | | dir | string | no | ltr | rtl | | displayImage | boolean | no | true | false | | promoType | string | no | regular | top |

Headline Props

| Argument | Type | Required | Default | Example | | --------- | ---- | -------- | ------- | ------- | | Script | object | yes | latin | { canon: { groupA: { fontSize: '28', lineHeight: '32',}, groupB: { fontSize: '32', lineHeight: '36', }, groupD: { fontSize: '44', lineHeight: '48', }, }, trafalgar: { groupA: { fontSize: '20', lineHeight: '24', }, groupB: { fontSize: '24', lineHeight: '28', }, groupD: { fontSize: '32', lineHeight: '36', }, }, } | | service | string | yes | N/A | 'news' | | promoHasImage | bool | no | true | false | | promoType | string | no | regular | top |

Summary Props

| Argument | Type | Required | Default | Example | | --------- | ---- | -------- | ------- | ------- | | Script | object | yes | latin | { canon: { groupA: { fontSize: '28', lineHeight: '32',}, groupB: { fontSize: '32', lineHeight: '36', }, groupD: { fontSize: '44', lineHeight: '48', }, }, trafalgar: { groupA: { fontSize: '20', lineHeight: '24', }, groupB: { fontSize: '24', lineHeight: '28', }, groupD: { fontSize: '32', lineHeight: '36', }, }, } | | service | string | yes | N/A | 'news' | | promoHasImage | bool | no | true | false | | promoType | string | no | regular | top |

IndexAlsos

The Index Alsos are links to stories that are related to the top story.

Within the IndexAlsos component there is a Visually Hidden level 4 heading, which announces text passed as prop.

When there are more than one Index Alsos, they should be wrapped in a list item IndexAlsosLi within an unordered list IndexAlsosUl with the role listitem and list respectively.

On the other hand, when there is exactly one Index Also, it should use the IndexAlso component and it should not be contained within a list.

Props

IndexAlsos Props

| Argument | Type | Required | Default | Example | | -------- | ---- | -------- | ------- | -------------- | | children | node | yes | N/A | <IndexAlsosUl><IndexAlsosLi script={latin} service="news" url="https://www.bbc.co.uk/news" mediaIndicator={<MediaIndicator service="news" type="video" indexAlsos/>}>Related content 1</IndexAlsosLi><IndexAlsosLi script={latin} service="news" url="https://www.bbc.co.uk/news">Related content 2</IndexAlsosLi></IndexAlsosUl>| | offScreenText | string | no | null | Related content |

Data attributes, such as data-e2e can be passed in for testing as well.

IndexAlsoUl Props

| Argument | Type | Required | Default | Example | | -------- | ---- | -------- | ------- | -------------- | | children | node | yes | N/A | <IndexAlsosLi script={latin} service="news" url="https://www.bbc.co.uk/news" mediaIndicator={<MediaIndicator service="news" type="video" indexAlsos/>}>Related content 1</IndexAlsosLi><IndexAlsosLi script={latin} service="news url="https://www.bbc.co.uk/news">Related content 2</IndexAlsosLi>|

IndexAlsoLi Props

| Argument | Type | Required | Default | Example | | -------------- | ------ | -------- | ------- | -------- | | children | node | yes | N/A | This is a headline | | script | object | yes | latin | { canon: { groupA: { fontSize: '28', lineHeight: '32',}, groupB: { fontSize: '32', lineHeight: '36', }, groupD: { fontSize: '44', lineHeight: '48', }, }, trafalgar: { groupA: { fontSize: '20', lineHeight: '24', }, groupB: { fontSize: '24', lineHeight: '28', }, groupD: { fontSize: '32', lineHeight: '36', }, }, }| | service | string | yes | N/A | 'news'| | url | string | yes | N/A | 'https://www.bbc.co.uk/news'| | dir | string | no | ltr | rtl | | mediaIndicator | node | no | null | <MediaIndicator service="news" type="video" indexAlsos/> | | mediaType | string | no | null | Video |

IndexAlso Props

| Argument | Type | Required | Default | Example | | -------------- | ------ | -------- | ------- | -------- | | children | node | yes | N/A | This is a headline | | script | object | yes | latin | { canon: { groupA: { fontSize: '28', lineHeight: '32',}, groupB: { fontSize: '32', lineHeight: '36', }, groupD: { fontSize: '44', lineHeight: '48', }, }, trafalgar: { groupA: { fontSize: '20', lineHeight: '24', }, groupB: { fontSize: '24', lineHeight: '28', }, groupD: { fontSize: '32', lineHeight: '36', }, }, }| | service | string | yes | N/A | 'news'| | url | string | yes | N/A | 'https://www.bbc.co.uk/news'| | dir | string | no | ltr | rtl | | mediaIndicator | node | no | null | <MediaIndicator service="news" type="video" indexAlsos/> | | mediaType | string | no | null | Video |

Usage

The typical use-case of this component is as displayed below. A Image sits on the left side of the promo with info elements on the right, except in Leading stories which are reversed. These info elements are typically a headline, text summary paragraph and timestamp. The Headline and Summary components are provided by this package and can be imported as seen below.

This component also has an option to display a media indicator, which consists of a play icon and duration of the media, if that data is provided.

The promoType prop of top can be passed to adopt a vertical card layout under 600px. At breakpoints above 600px a horizontal layout is maintained with the image and text summary each occupying 1/2 of the parent container.

On the other hand, a promoType prop of leading can be passed to place the Info on the left side and the Image or the right side of the component. The image occupies 2/3 of the parent container and the text summary occupies 1/3.

This prop must be passed to the StoryPromo, Headline and Summary components.

import React, { Fragment } from 'react';
import StoryPromo, {
  Headline,
  Summary,
  Link,
  IndexAlsos,
  IndexAlso,
  IndexAlsosUl,
  IndexAlsosLi,
} from '@bbc/psammead-story-promo';
import MediaIndicator from '@bbc/psammead-media-indicator';
import { latin } from '@bbc/gel-foundations/scripts';
import LiveLabel from '@bbc/psammead-live-label';
import VisuallyHiddenText from '@bbc/psammead-visually-hidden-text';

const Image = <img src="https://foobar.com/image.jpg" />;

const IndexAlsosComponent = ({ alsoItems, script, service }) => (
  //This example doesn't show how the alsoItems are destructured to get the respective data
  <IndexAlsos offScreenText="Related content">
    {alsoItems.length > 1 ? (
      <IndexAlsosUl>
        <IndexAlsosLi
          script={script}
          service={service}
          url="https://www.bbc.co.uk/news"
          mediaIndicator={
            <MediaIndicator service={service} type="video" indexAlsos />
          }
        >
          Related text 1
        </IndexAlsosLi>
        <IndexAlsosLi
          script={script}
          service={service}
          url="https://www.bbc.co.uk/news"
        >
          Related text 2
        </IndexAlsosLi>
      </IndexAlsosUl>
    ) : (
      <IndexAlso>Related text</IndexAlso>
    )}
  </IndexAlsos>
);

const Info = ({ isLive, alsoItems }) => (
  <Fragment>
    <Headline script={latin} service="news" promoType="top">
      <Link href="https://www.bbc.co.uk/news">
        {isLive ? (
          <LiveLabel service="news" dir={dir} ariaHidden offScreenText="Live">
            The headline of the live promo
          </LiveLabel>
        ) : (
          'The headline of the promo'
        )}
      </Link>
    </Headline>
    <Summary script={latin} service="news" promoType="top">
      The summary of the promo
    </Summary>
    <time>12 March 2019</time>
    {topStory && alsoItems && (
      <IndexAlsosComponent
        alsoItems={alsoItems}
        script={latin}
        service="news"
      />
    )}
  </Fragment>
);

<StoryPromo image={Image} info={Info({ isLive: false })} promoType="top" />;

When to use this component

The StoryPromo component is designed to be used within a link element to allow the user to navigate to the story on another page.

Accessibility notes

This component uses full semantic markup for the Headline, Summary, and Link, using h3, p and a respectively. Other accessibility factors such as image alt text and time elements are passed in as props and aren't explicitly set in this component.

The link is nested inside the h3 for better support with VoiceOver Mac and Safari. We use the faux block link pattern which makes the entire block clickable, whilst also enabling links nested within in that block to also be clickable.

The LiveLabel example above shows this component being hidden to screen readers, and has visually hidden text rendered alongside it. This is to ensure the screen reader announces the word 'Live' correctly. This does not need to be accounted for in other languages.

Roadmap

Contributing

Psammead is completely open source. We are grateful for any contributions, whether they be new components, bug fixes or general improvements. Please see our primary contributing guide which can be found at the root of the Psammead repository.

Code of Conduct

We welcome feedback and help on this work. By participating in this project, you agree to abide by the code of conduct. Please take a moment to read it.

License

Psammead is Apache 2.0 licensed.