-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add Stories for o-banner demos.
Destroy Method: Adds a `destroy` method to o-banner. This is used in the o-banner Story to clean up the close button when re-rendered, which o-banner dynamically creates on `init`. This is required to support the `suppressCloseButton` Story control. Hidden Controls: It appears banner headings (headingLong/headingShort) should only be used with the small/compact layout variants. Not with the default banner style which is full bleed. However it is possible to use Story controls to create that view. `@storybook/addon-knobs` (deprecated) allowed dynamic knobs, so we could hide the heading controls if the default layout was selected. That's not possible with `@storybook/addon-controls`: storybookjs/storybook#11984 I think that's probably a good thing. Support for dynamic controls was worked on but not merge. It's a poor experience when controls shift around. storybookjs/storybook#13890 For now this commit hides the layout control on layout demos, and hides the heading controls from the default layout demo, to avoid showing the discouraged heading + layout combination. However it is still possible to select the base layout with heading on the theme specific demos, so that the small/compact layout can also be selected which is allowed. This could be resolved by exporting 2 templates, one for each kind of banner / usecase. This could make components easier to reason with and maintain. For now this commit sticks to one banner template as coming up with a name without history / useage guidelines is difficult, and we don't know that users aren't already using headings with the base layout - though we never intended it as far as I can tell. No Custom Theme Demo: The custom theme demo has not been migrated to a Story yet. https://registry.origami.ft.com/components/[email protected]#demo-custom-theme I'm not sure there is value, and maybe harm, in showing made up customised styles alongside those with brand/design approval. Plus it's not clear how to re-create the style without understanding Sass and inspecting demo code. We probably want to have stories for customised components at a later date, with improved guidelines around them and demo Sass/JS pane. See related issue: #370 No Custom Call To Action Demo: https://registry.origami.ft.com/components/[email protected]#demo-custom-call-to-action-layout The description of the demo starts "Although not recommended for design consistency..." Let's not recomend it with a demo.
- Loading branch information
Showing
7 changed files
with
3,489 additions
and
3,922 deletions.
There are no files selected for viewing
This file contains 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 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 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 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,105 @@ | ||
export interface BannerSubmitButton { | ||
action: string; | ||
encoding: string; | ||
method: string; | ||
copy: string; | ||
} | ||
|
||
export interface BannerLink { | ||
copy: string; | ||
url: string; | ||
} | ||
|
||
export interface BannerProps { | ||
suppressCloseButton?: boolean; | ||
headingLong?: string; | ||
headingShort?: string; | ||
contentLong: string; | ||
contentShort?: string; | ||
closeButtonLabel?: string; | ||
primaryAction?: BannerLink | BannerSubmitButton; | ||
secondaryAction?: BannerLink | ||
theme: 'product' | 'marketing' | ''; | ||
layout: 'small' | 'compact' | ''; | ||
} | ||
|
||
function isBannerSubmitButton(action: BannerSubmitButton | BannerLink): action is BannerSubmitButton { | ||
return (action as BannerSubmitButton).action !== undefined; | ||
} | ||
|
||
export function Banner({ | ||
suppressCloseButton = false, | ||
headingLong = '', | ||
headingShort = '', | ||
contentLong = 'Hello!', | ||
contentShort = '', | ||
closeButtonLabel = 'Close', | ||
primaryAction = { | ||
copy: 'OK', | ||
url: '#', | ||
}, | ||
secondaryAction = undefined, | ||
theme = '', | ||
layout = '', | ||
}: BannerProps) { | ||
const classNames = ['o-banner']; | ||
const dataAttributes = {}; | ||
|
||
if(layout) { | ||
classNames.push(`o-banner--${layout}`); | ||
} | ||
|
||
if(theme) { | ||
classNames.push(`o-banner--${theme}`); | ||
} | ||
|
||
if(suppressCloseButton) { | ||
dataAttributes['data-o-banner-suppress-close-button'] = true; | ||
} | ||
|
||
return ( | ||
<div className={classNames.join(' ')} {...dataAttributes} data-o-component="o-banner"> | ||
<div className="o-banner__outer"> | ||
<div className="o-banner__inner" data-o-banner-inner> | ||
{contentLong && ( | ||
<div className="o-banner__content o-banner__content--long"> | ||
{headingLong && ( | ||
<header className="o-banner__heading"> | ||
<h2>{headingLong}</h2> | ||
</header> | ||
)} | ||
<p>{contentLong}</p> | ||
</div> | ||
)} | ||
{contentShort && ( | ||
<div className="o-banner__content o-banner__content--short"> | ||
{headingShort && ( | ||
<header className="o-banner__heading"> | ||
<h2>{headingShort}</h2> | ||
</header> | ||
)} | ||
<p>{contentShort}</p> | ||
</div> | ||
)} | ||
<div className="o-banner__actions"> | ||
{primaryAction && !isBannerSubmitButton(primaryAction) && ( | ||
<div className="o-banner__action"> | ||
<a href="{primaryAction.url}" className="o-banner__button">{primaryAction.copy}</a> | ||
</div> | ||
)} | ||
{primaryAction && isBannerSubmitButton(primaryAction) && ( | ||
<form className="o-banner__action" method="{primaryAction.method}" encType="{primaryAction.encoding}" action="{primaryAction.action}"> | ||
<input className="o-banner__button" type="submit" value="{primaryAction.copy}" /> | ||
</form> | ||
)} | ||
{secondaryAction && ( | ||
<div className="o-banner__action o-banner__action--secondary"> | ||
<a href="{secondaryAction.url}" className="o-banner__link">{secondaryAction.copy}</a> | ||
</div> | ||
)} | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} |
This file contains 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,7 @@ | ||
@import "@financial-times/o-fonts/main"; | ||
@import "@financial-times/o-normalise/main"; | ||
@include oFonts(); | ||
@include oNormalise(); | ||
|
||
@import "@financial-times/o-banner/main"; | ||
@include oBanner(); |
This file contains 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,143 @@ | ||
import {withDesign} from 'storybook-addon-designs'; | ||
import {Banner} from '../src/tsx/banner'; | ||
import {useEffect} from 'react'; | ||
import javascript from '../main'; | ||
import './banner.scss'; | ||
import withHtml from 'origami-storybook-addon-html'; | ||
|
||
export default { | ||
title: 'Banner', | ||
component: Banner, | ||
decorators: [withDesign, withHtml], | ||
args: { | ||
}, | ||
parameters: { | ||
design: { | ||
type: 'figma', | ||
url: 'https://www.figma.com/file/MyHQ1qdwYyek5IBdhEEaND/FT-UI-Library?node-id=0%3A1489', | ||
}, | ||
guidelines: { | ||
notion: '37cdc7ac2cac4d60a4c9f451c47a4647', | ||
}, | ||
html: {}, | ||
}, | ||
}; | ||
|
||
const Story = args => { | ||
useEffect(() => { | ||
let banners = javascript.init(); | ||
return function cleanup() { | ||
banners = Array.isArray(banners) ? banners : [banners]; | ||
banners.forEach(banner => banner.destroy()); | ||
} | ||
}, [args.suppressCloseButton]); | ||
return <Banner {...args} />; | ||
}; | ||
|
||
export const Default = Story.bind({}); | ||
Default.args = { | ||
suppressCloseButton: false, | ||
contentLong: 'Try the new compact homepage. A list view of today\'s homepage with fewer images.', | ||
contentShort: 'Try it now', | ||
closeButtonLabel: 'Close', | ||
primaryAction: { | ||
copy: 'Try it now', | ||
url: '#', | ||
}, | ||
secondaryAction: { | ||
copy: 'Give feedback', | ||
url: '#' | ||
}, | ||
theme: '', | ||
layout: '' | ||
}; | ||
// Exclude layout and heading controls to discourage use of the default layout with a heading. | ||
// https://github.com/Financial-Times/origami/pull/523 | ||
Default.parameters = {controls: { exclude: ['headingLong', 'headingShort', 'layout'] }}; | ||
|
||
|
||
export const Small = Story.bind({}); | ||
Small.args = { | ||
suppressCloseButton: false, | ||
headingLong: 'FT Compact', | ||
headingShort: 'FT Compact', | ||
contentLong: 'Try the new compact homepage. A list view of today\'s homepage with fewer images.', | ||
contentShort: 'Try it now', | ||
closeButtonLabel: 'Close', | ||
primaryAction: { | ||
copy: 'Try it now', | ||
url: '#', | ||
}, | ||
secondaryAction: { | ||
copy: 'Give feedback', | ||
url: '#' | ||
}, | ||
theme: '', | ||
layout: 'small' | ||
}; | ||
// Exclude layout to discourage use of the default layout with a heading. | ||
// https://github.com/Financial-Times/origami/pull/523 | ||
Small.parameters = {controls: { exclude: ['layout'] }}; | ||
|
||
export const Compact = Story.bind({}); | ||
Compact.args = { | ||
suppressCloseButton: false, | ||
headingLong: 'FT Compact', | ||
headingShort: 'FT Compact', | ||
contentLong: 'Try the new compact homepage. A list view of today\'s homepage with fewer images.', | ||
contentShort: 'Try it now', | ||
closeButtonLabel: 'Close', | ||
primaryAction: { | ||
copy: 'Try it now', | ||
url: '#', | ||
}, | ||
secondaryAction: { | ||
copy: 'Give feedback', | ||
url: '#' | ||
}, | ||
theme: '', | ||
layout: 'compact' | ||
}; | ||
// Exclude layout to discourage use of the default layout with a heading. | ||
// https://github.com/Financial-Times/origami/pull/523 | ||
Compact.parameters = {controls: { exclude: ['layout'] }}; | ||
|
||
export const Marketing = Story.bind({}); | ||
Marketing.args = { | ||
suppressCloseButton: false, | ||
headingLong: 'FT Compact', | ||
headingShort: 'FT Compact', | ||
contentLong: 'Try the new compact homepage. A list view of today\'s homepage with fewer images.', | ||
contentShort: 'Try it now', | ||
closeButtonLabel: 'Close', | ||
primaryAction: { | ||
copy: 'Try it now', | ||
url: '#', | ||
}, | ||
secondaryAction: { | ||
copy: 'Give feedback', | ||
url: '#' | ||
}, | ||
theme: 'marketing', | ||
layout: 'small' | ||
}; | ||
|
||
export const Product = Story.bind({}); | ||
Product.args = { | ||
suppressCloseButton: false, | ||
headingLong: 'FT Compact', | ||
headingShort: 'FT Compact', | ||
contentLong: 'Try the new compact homepage. A list view of today\'s homepage with fewer images.', | ||
contentShort: 'Try it now', | ||
closeButtonLabel: 'Close', | ||
primaryAction: { | ||
copy: 'Try it now', | ||
url: '#', | ||
}, | ||
secondaryAction: { | ||
copy: 'Give feedback', | ||
url: '#' | ||
}, | ||
theme: 'product', | ||
layout: 'small' | ||
}; |
Oops, something went wrong.