-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #88 from fourkitchens/develop
Release - 05/27/2024 -1
- Loading branch information
Showing
6 changed files
with
328 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# CTA Banner Component API | ||
|
||
The CTA (Call to Action) Banner component is designed to create prominent and customizable calls to action. Below is the documentation for the CTA Banner component. | ||
|
||
## Import | ||
|
||
```javascript | ||
import { CtaBanner } from 'forcepoint-shared-components'; | ||
``` | ||
|
||
## Props | ||
|
||
| Name | Type | Default | Description | | ||
| --- | --- | --- | --- | | ||
| eyebrow | `string` | `-` | The eyebrow text of the call to action. | | ||
| title | `string` | `-` | The main text of the call to action. | | ||
| theme | `azure` \| `black` \| `navy` \| `white` | `-` | Additional theme for the CTA component. | | ||
| renderedTitleComponent | `ReactNode` | - | Renders the title using and external component. | | ||
| primaryButton | `CtaButtonDetails` | `-` | Details of the primary button associated with the call to action. See the `CtaButtonDetails` type for details. | | ||
| buttonComponent | `ElementType` | `a` | Specifies the root node's element type for the primary button. It accepts a string for a standard HTML element or a custom component. Defaults to a (link). | | ||
| image | `CtaImageDetails` | `-` | Details of the image to be displayed within the call to action. See the `CtaImageDetails` type for details. | | ||
| renderedImageComponent | `ReactNode` | - | Renders the image using and external component. | | ||
| backgroundImage | `CtaImageDetails` | `-` | Details of the background image to be displayed within the call to action. See the `CtaImageDetails` type for details. | | ||
| imageComponent | `ElementType` | `img` | Specifies the root node's element type for the image. It accepts a string for a standard HTML element or a custom component. Defaults to `img`. | | ||
|
||
|
||
### CtaButtonDetails | ||
|
||
| Name | Type | Description | | ||
| --- | --- | --- | | ||
| title | `string` | Required. The title of the link. | | ||
| url | `string` | Required. The URL the link directs to. | | ||
|
||
### CtaImageDetails | ||
|
||
| Name | Type | Description | | ||
| --- | --- | --- | | ||
| src | `string` | Required. The source URL of the image. | | ||
| alt | `string` | Required. Alternative text for the image. | | ||
| height | `string\|number` | Optional. The height of the image. If provided, it sets the `height` attribute on the image tag. | | ||
| width | `string\|number` | Optional. The width of the image. If provided, it sets the `width` attribute on the image tag. | | ||
|
||
### Usage | ||
|
||
```javascript | ||
import { CtaBanner } from 'forcepoint-shared-components'; | ||
|
||
<CtaBanner | ||
eyebrow={bannerEyebrow} | ||
renderedTitleComponent={renderedContent} | ||
primaryButton={buttonDetails} | ||
buttonComponent={Link} | ||
image={imageDetails} | ||
imageComponent={Image} | ||
backgroundImage={backgroundImageDetails} | ||
theme={ctaBannerStyle as CtaBannerTheme} | ||
/> | ||
``` |
23 changes: 23 additions & 0 deletions
23
src/lib/components/02-components/cta-banner/cta-banner.stories.tsx
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,23 @@ | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
import CtaBanner from './cta-banner'; | ||
|
||
const meta = { | ||
title: 'Components/CTA Banner', | ||
component: CtaBanner, | ||
} satisfies Meta<typeof CtaBanner>; | ||
|
||
export default meta; | ||
type Story = StoryObj<typeof meta>; | ||
|
||
export const Default: Story = { | ||
args: { | ||
title: | ||
'Find it hard to keep pace with modern network demands? Read the Four Steps to Future-Ready Network Security.', | ||
eyebrow: 'Independent Report', | ||
primaryButton: { | ||
title: 'Read Now', | ||
url: '#', | ||
}, | ||
theme: 'azure', | ||
}, | ||
}; |
158 changes: 158 additions & 0 deletions
158
src/lib/components/02-components/cta-banner/cta-banner.tsx
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,158 @@ | ||
import { | ||
CSSProperties, | ||
ComponentPropsWithoutRef, | ||
ElementType, | ||
ReactNode, | ||
} from 'react'; | ||
import { cn } from '../../../utils/tailwind-merge'; | ||
import Button, { ButtonColorVariant } from '../../01-elements/button/button'; | ||
import Typography from '../../01-elements/typography/typography'; | ||
|
||
export interface CtaBannerProps extends ComponentPropsWithoutRef<'div'> { | ||
eyebrow?: string; | ||
title?: string; | ||
renderedTitleComponent?: ReactNode; | ||
primaryButton?: CtaButtonDetails; | ||
buttonComponent?: ElementType; | ||
image?: CtaBannerImageDetails; | ||
renderedImageComponent?: ReactNode; | ||
backgroundImage?: CtaBannerImageDetails; | ||
imageComponent?: ElementType; | ||
theme: CtaBannerTheme; | ||
} | ||
|
||
export type CtaButtonDetails = { | ||
title: string; | ||
url: string; | ||
}; | ||
|
||
export type CtaBannerImageDetails = { | ||
alt: string; | ||
height?: string | number; | ||
src: string; | ||
width?: string | number; | ||
}; | ||
|
||
export type CtaBannerTheme = 'azure' | 'black' | 'violette' | 'navy'; | ||
|
||
type CtaBannerColorSchema = { | ||
button: ButtonColorVariant; | ||
eyebrow: string; | ||
title: string; | ||
wrapper: string; | ||
}; | ||
|
||
const colorSchema: { [key in CtaBannerTheme]: CtaBannerColorSchema } = { | ||
azure: { | ||
button: 'blue', | ||
eyebrow: 'text-violette', | ||
title: 'text-navy', | ||
wrapper: 'bg-azure', | ||
}, | ||
black: { | ||
button: 'sandwisp', | ||
eyebrow: 'text-sandwisp', | ||
title: 'text-white', | ||
wrapper: 'bg-black', | ||
}, | ||
violette: { | ||
button: 'sandwisp', | ||
eyebrow: 'text-sandwisp', | ||
title: 'text-white', | ||
wrapper: 'bg-violette', | ||
}, | ||
navy: { | ||
button: 'white', | ||
eyebrow: 'text-sandwisp', | ||
title: 'text-white', | ||
wrapper: 'bg-navy', | ||
}, | ||
}; | ||
|
||
export default function CtaBanner({ | ||
eyebrow, | ||
title, | ||
renderedTitleComponent, | ||
primaryButton, | ||
buttonComponent: ButtonElement = 'a', | ||
image, | ||
renderedImageComponent, | ||
backgroundImage, | ||
imageComponent: ImageElement = 'img', | ||
theme, | ||
className, | ||
}: CtaBannerProps) { | ||
const renderedTitle = renderedTitleComponent ? ( | ||
renderedTitleComponent | ||
) : title ? ( | ||
<Typography className={colorSchema[theme].title} variant="h3"> | ||
{title} | ||
</Typography> | ||
) : null; | ||
|
||
const renderedPrimaryButton = primaryButton && ( | ||
<Button | ||
animated | ||
as="link" | ||
href={primaryButton.url} | ||
component={ButtonElement} | ||
color={colorSchema[theme].button} | ||
className="mt-md w-full justify-center px-14 py-4 text-h4 md:ml-10 md:mt-0 md:min-w-[230px] lg:w-60"> | ||
{primaryButton.title} | ||
</Button> | ||
); | ||
|
||
const renderedImage = renderedImageComponent ? ( | ||
renderedImageComponent | ||
) : image ? ( | ||
<ImageElement | ||
className="mx-auto h-full w-full object-contain" | ||
src={image.src} | ||
alt={image.alt} | ||
{...(image.width && { width: image.width })} | ||
{...(image.height && { height: image.height })} | ||
/> | ||
) : null; | ||
|
||
const bgImageStyles: CSSProperties = {}; | ||
if (backgroundImage) { | ||
bgImageStyles.backgroundImage = `url(${backgroundImage.src})`; | ||
} | ||
|
||
return ( | ||
<div | ||
style={bgImageStyles} | ||
className={cn( | ||
'bg-cover bg-center p-10', | ||
colorSchema[theme].wrapper, | ||
className, | ||
)}> | ||
<div | ||
className={cn('flex w-full flex-col md:flex-row', { | ||
'max-w-screen-lg md:mx-auto md:my-0 md:justify-center': | ||
renderedImage === null, | ||
})}> | ||
{renderedImage && ( | ||
<div className="relative mb-5 aspect-[16/9] w-auto md:mb-0 md:mr-10 md:aspect-[1/1] md:w-[350px]"> | ||
{renderedImage} | ||
</div> | ||
)} | ||
<div className="flex flex-col md:flex-row md:items-center"> | ||
<div className="max-w-screen-sm"> | ||
{eyebrow && ( | ||
<span | ||
className={cn( | ||
'mb-3 block text-h5 font-semibold uppercase', | ||
colorSchema[theme].eyebrow, | ||
)}> | ||
{eyebrow} | ||
</span> | ||
)} | ||
{renderedTitle} | ||
</div> | ||
{renderedPrimaryButton} | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} |
19 changes: 19 additions & 0 deletions
19
src/lib/components/02-components/social-share/social-share.stories.tsx
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,19 @@ | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
import SocialShare from './social-share'; | ||
|
||
const meta = { | ||
title: 'Components/Social Share', | ||
component: SocialShare, | ||
} satisfies Meta<typeof SocialShare>; | ||
|
||
export default meta; | ||
type Story = StoryObj<typeof meta>; | ||
|
||
export const Default: Story = { | ||
args: { | ||
url: 'https://www.example.com', | ||
title: 'Example Title', | ||
shareText: 'Share on', | ||
ariaNavLabel: 'Social media sharing', | ||
}, | ||
}; |
63 changes: 63 additions & 0 deletions
63
src/lib/components/02-components/social-share/social-share.tsx
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,63 @@ | ||
import { cn } from '../../../utils/tailwind-merge'; | ||
import { FacebookIcon, LinkedinIcon, TwitterIcon } from '../../00-tokens/icons'; | ||
|
||
export type SocialShareProps = { | ||
url: string; | ||
title: string; | ||
shareText?: string; | ||
className?: string; | ||
ariaNavLabel?: string; | ||
}; | ||
|
||
function genericSocialShare(url: string, socialNetwork: string) { | ||
window.open(url, socialNetwork, 'toolbar=0,status=0,width=648,height=420'); | ||
} | ||
|
||
export default function SocialShare({ | ||
url, | ||
title, | ||
className, | ||
shareText = 'Share on', | ||
ariaNavLabel = 'Social media sharing', | ||
}: SocialShareProps) { | ||
const socialButtons = [ | ||
{ | ||
platform: 'LinkedIn', | ||
shareUrl: `https://www.linkedin.com/shareArticle?mini=true&url=${encodeURIComponent(url)}&title=${encodeURIComponent(title)}`, | ||
icon: <LinkedinIcon className="h-[20px] w-[20px] text-grey" />, | ||
ariaLabel: `${shareText} LinkedIn`, | ||
}, | ||
{ | ||
platform: 'Twitter', | ||
shareUrl: `http://twitter.com/share?text=${title}&url=${encodeURIComponent(url)}`, | ||
icon: <TwitterIcon className="h-[20px] w-[20px] text-grey" />, | ||
ariaLabel: `${shareText} Twitter`, | ||
}, | ||
{ | ||
platform: 'Facebook', | ||
shareUrl: `http://www.facebook.com/sharer.php?u=${encodeURIComponent(url)}`, | ||
icon: <FacebookIcon className="h-[20px] w-[20px] text-grey" />, | ||
ariaLabel: `${shareText} Facebook`, | ||
}, | ||
]; | ||
|
||
return ( | ||
<nav aria-label={ariaNavLabel} className={className}> | ||
<ul className={cn('flex gap-sm md:flex-col')}> | ||
{socialButtons.map(({ platform, shareUrl, icon, ariaLabel }) => ( | ||
<li key={platform}> | ||
<button | ||
title={ariaLabel} | ||
aria-label={ariaLabel} | ||
onClick={() => genericSocialShare(shareUrl, ariaLabel)} | ||
className={cn( | ||
'flex h-[40px] w-[40px] items-center justify-center rounded-[10px] bg-azure hover:bg-mercury', | ||
)}> | ||
{icon} | ||
</button> | ||
</li> | ||
))} | ||
</ul> | ||
</nav> | ||
); | ||
} |
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