Skip to content

Commit 5503b7e

Browse files
DS-1445 | CTA Group component (#501)
* Update next and storyblok packages * Beginning using Momentum CTA components * Keep working on CtaLinks * ts errors and WIP * Gradient links and other styles; remove Masthead component * Button align and styles * CTA icons * Use CtaLink for local footer links * Remove flexbox wrapper from CtaContent * Add variant prop for styles not mapped to SbCtaLink; special icon styles * Remove react loading skeleton and update sa11y * test * Update storyblok packages * Add editor check to access key in window URL for storyblokInit for Storyblok provider * Only do the editor check for the token in the URL for storyblok provider * test * test * Undo * try next 15.3.0 * Remove params of getStoryblokApi utility * fixup URL param for editor token * undo accidentally changed path of not-found * test * Add placeholder components * import storyblok things from rsc directory * Update components/Storyblok/SbRowOneColumn.tsx Co-authored-by: Sherakama <sheamck@stanford.edu> * Update components/Storyblok/SbRowOneColumn.tsx Co-authored-by: Sherakama <sheamck@stanford.edu> * Extract reusable subcomponent for link groups * CtaGroup component * use destructured linkText prop * Reduce leading in CTAs so it more closely match the live site --------- Co-authored-by: Sherakama <sheamck@stanford.edu>
1 parent f951f5a commit 5503b7e

File tree

9 files changed

+82
-6
lines changed

9 files changed

+82
-6
lines changed

components/CreateBloks.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ import { StoryblokServerComponent, type SbBlokData } from '@storyblok/react/rsc'
22

33
type CreateBloksProps = {
44
blokSection: SbBlokData[];
5+
isListItems?: boolean;
56
[k: string]: unknown;
67
};
78

8-
export const CreateBloks = ({ blokSection, ...props }: CreateBloksProps) => {
9-
if (blokSection) {
9+
export const CreateBloks = ({ blokSection, isListItems, ...props }: CreateBloksProps) => {
10+
if (blokSection && isListItems) {
11+
return blokSection.map((blok) => <li key={blok._uid}><StoryblokServerComponent blok={blok} {...props} /></li>);
12+
} else if (blokSection) {
1013
return blokSection.map((blok) => <StoryblokServerComponent key={blok._uid} blok={blok} {...props} />);
1114
}
1215

components/Cta/Cta.styles.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { type CtaIconLeftMarginType } from './Cta.types';
22

33
export const cta = 'group/cta transition-all';
4-
export const buttonBase = 'block font-normal w-fit no-underline hocus:underline';
4+
export const buttonBase = 'block font-normal w-fit no-underline hocus:underline leading-tight';
55
// hocus to plum dark gradient instead of solid plum dark to avoid a flash of white background on hocus
66
export const gradientButtonBase = 'bg-gradient-to-tr hocus:from-plum-dark hocus:to-plum-dark text-white hocus:text-white';
7-
export const textLinkBase = 'block font-semibold w-fit no-underline text-18 md:text-20';
7+
export const textLinkBase = 'block font-semibold w-fit no-underline text-18 md:text-20 leading-tight';
88
export const gradientTextLinkBase = 'bg-clip-text bg-gradient-to-tr text-transparent hocus:text-transparent';
99

1010
// Maps to linkButtonStyle props in SbCtaLink. Only used for the Button style.
@@ -107,3 +107,5 @@ export const ctaAligns = {
107107
center: 'su-text-center mx-auto',
108108
right: 'su-text-right ml-auto mr-0',
109109
};
110+
111+
export const ctaGroup = 'list-unstyled gap-x-08em gap-y-1em [&_li]:mb-0 [&_a]:text-09em [&_a]:md:text-20 [&_a]:p-07em [&_a]:md:pt-11 [&_a]:md:pb-12 [&_a]:md:px-30';

components/Cta/Cta.types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,5 @@ export interface CtaCommonProps {
2929
mb?: MarginType;
3030
children?: React.ReactNode;
3131
}
32+
33+
export type CtaGroupDisplayType = 'inline' | 'inline-block';

components/Cta/CtaGroup.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { cnb } from 'cnbuilder';
2+
import { FlexBox } from '@/components/FlexBox';
3+
import * as styles from './Cta.styles';
4+
import * as types from './Cta.types';
5+
6+
type CtaGroupProps = React.HTMLAttributes<HTMLDivElement> & {
7+
display: types.CtaGroupDisplayType;
8+
};
9+
10+
export const CtaGroup = ({
11+
display = 'inline-block',
12+
className,
13+
children,
14+
...props
15+
}: CtaGroupProps) => {
16+
return (
17+
<FlexBox
18+
{...props}
19+
as="ul"
20+
direction={display === 'inline-block' ? 'row' : 'col'}
21+
wrap={display === 'inline-block' ? 'wrap' : 'nowrap'}
22+
justifyContent={display === 'inline-block' ? 'center' : 'start'}
23+
className={cnb(styles.ctaGroup, className)}
24+
>
25+
{children}
26+
</FlexBox>
27+
);
28+
};

components/Cta/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ export * from './CtaButton';
22
export * from './CtaExternalLink';
33
export * from './CtaNextLink';
44
export * from './CtaLink';
5+
export * from './CtaGroup';
56
export * from './Cta.styles';
67
export * from './Cta.types';

components/Storyblok/SbCtaGroup.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { storyblokEditable, type SbBlokData } from '@storyblok/react/rsc';
2+
import { CreateBloks } from '@/components/CreateBloks';
3+
import { CtaGroup, type CtaGroupDisplayType } from '@/components/Cta';
4+
import { getNumBloks } from '@/utilities/getNumBloks';
5+
6+
type SbCtaGroupProps = {
7+
blok: SbBlokData & {
8+
ctaLinks?: SbBlokData[];
9+
display?: CtaGroupDisplayType;
10+
};
11+
};
12+
13+
export const SbCtaGroup = (props: SbCtaGroupProps) => {
14+
const { ctaLinks, display } = props.blok;
15+
if (!getNumBloks(ctaLinks)) {
16+
return null; // Return null if there are no ctaLinks to display
17+
}
18+
19+
return (
20+
<CtaGroup display={display} {...storyblokEditable(props.blok)}>
21+
<CreateBloks blokSection={ctaLinks} isListItems />
22+
</CtaGroup>
23+
);
24+
};

components/Storyblok/SbCtaLink.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export const SbCtaLink = React.forwardRef<HTMLAnchorElement, SbCtaProps>((props,
3939
linkTextColor,
4040
} = props.blok;
4141

42-
if (!props.blok.linkText) {
42+
if (!linkText) {
4343
return null;
4444
}
4545

utilities/getNumBloks.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { type SbBlokData } from '@storyblok/react/rsc';
2+
/**
3+
* Returns the number of nested bloks when we use the CreateBloks utility.
4+
*
5+
* @param sbField - The Storyblok field to count bloks in.
6+
* @returns The number of bloks added to this Storyblok field.
7+
*/
8+
9+
export const getNumBloks = (sbField: SbBlokData[]) => {
10+
if (sbField?.length) {
11+
return sbField.length;
12+
}
13+
14+
return 0;
15+
};

utilities/storyblok.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@ import { SbStoryImage } from '@/components/Storyblok/SbStoryImage';
2121
import { SbSection } from '@/components/Storyblok/SbSection';
2222
import { SbRowOneColumn } from '@/components/Storyblok/SbRowOneColumn';
2323
import { SbBasicCard } from '@/components/Storyblok/SbBasicCard';
24+
import { SbCtaGroup } from '@/components/Storyblok/SbCtaGroup';
2425

2526
export const components = {
26-
// TODO DS-1417: Remove and clean up page
2727
page: SbPage,
2828
redirect: Redirect,
2929
storyPicker: SbStoryPicker,
3030
ctaLink: SbCtaLink,
31+
ctaGroup: SbCtaGroup,
3132
navItem: SbNavItem,
3233
lockup: SbLockup,
3334
// Cards

0 commit comments

Comments
 (0)