From 55e730f0dce1f3b29635a76055e3778b3b129b3e Mon Sep 17 00:00:00 2001 From: Sherakama Date: Fri, 2 Feb 2024 15:37:54 -0800 Subject: [PATCH 01/34] Bugfix: Add editor token. (#222) --- app/(editor)/editor/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/(editor)/editor/page.tsx b/app/(editor)/editor/page.tsx index 42ec3154..5faff6e9 100644 --- a/app/(editor)/editor/page.tsx +++ b/app/(editor)/editor/page.tsx @@ -38,7 +38,7 @@ const bridgeOptions = { * Init on the server. */ storyblokInit({ - accessToken: process.env.STORYBLOK_ACCESS_TOKEN, // Preview token because this is in server side. + accessToken: process.env.STORYBLOK_PREVIEW_EDITOR_TOKEN, // Preview token because this is in server side. use: [apiPlugin], apiOptions: { region: 'us', From 35c1c235f48def856864266b161a23ed6a53555d Mon Sep 17 00:00:00 2001 From: Github Action Date: Fri, 2 Feb 2024 23:48:39 +0000 Subject: [PATCH 02/34] 1.0.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index c6a1e67d..c9d07276 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ood-giving-campaign", - "version": "1.0.1", + "version": "1.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ood-giving-campaign", - "version": "1.0.1", + "version": "1.0.2", "dependencies": { "@heroicons/react": "^2.1.1", "@storyblok/react": "^3.0.8", diff --git a/package.json b/package.json index 0345fb4c..d485708e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ood-giving-campaign", - "version": "1.0.1", + "version": "1.0.2", "description": "Momentum", "author": "Stanford University", "keywords": [ From f770183d1f338185e8848446bb43c9e18ace79bf Mon Sep 17 00:00:00 2001 From: Sherakama Date: Fri, 2 Feb 2024 16:12:53 -0800 Subject: [PATCH 03/34] Bugfix: Add editor token... Everywhere (#224) --- app/(editor)/editor/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/(editor)/editor/page.tsx b/app/(editor)/editor/page.tsx index 5faff6e9..e193e9c0 100644 --- a/app/(editor)/editor/page.tsx +++ b/app/(editor)/editor/page.tsx @@ -95,7 +95,7 @@ async function getStoryData({ path }: PageProps['searchParams']): Promise { - const validationString = searchParams['_storyblok_tk[space_id]'] + ':' + process.env.STORYBLOK_ACCESS_TOKEN + ':' + searchParams['_storyblok_tk[timestamp]']; + const validationString = searchParams['_storyblok_tk[space_id]'] + ':' + process.env.STORYBLOK_PREVIEW_EDITOR_TOKEN + ':' + searchParams['_storyblok_tk[timestamp]']; const validationToken = crypto.createHash('sha1').update(validationString).digest('hex'); if (searchParams['_storyblok_tk[token]'] == validationToken && Number(searchParams['_storyblok_tk[timestamp]']) > Math.floor(Date.now()/1000)-3600) { From b0040c6f2d23c14d622cf8c7377cf05ad73da63d Mon Sep 17 00:00:00 2001 From: Github Action Date: Sat, 3 Feb 2024 00:16:01 +0000 Subject: [PATCH 04/34] 1.0.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index c9d07276..8f6d8c1e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ood-giving-campaign", - "version": "1.0.2", + "version": "1.0.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ood-giving-campaign", - "version": "1.0.2", + "version": "1.0.3", "dependencies": { "@heroicons/react": "^2.1.1", "@storyblok/react": "^3.0.8", diff --git a/package.json b/package.json index d485708e..370de7fb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ood-giving-campaign", - "version": "1.0.2", + "version": "1.0.3", "description": "Momentum", "author": "Stanford University", "keywords": [ From 9dfefafca1cb1415fc8a6191c9eb6342b1adb854 Mon Sep 17 00:00:00 2001 From: Yvonne Tang <42749717+yvonnetangsu@users.noreply.github.com> Date: Mon, 5 Feb 2024 16:06:51 -0800 Subject: [PATCH 05/34] datasource heroOverlay black-10 typo (#226) --- utilities/datasource.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/datasource.ts b/utilities/datasource.ts index 5bfee141..3953ec46 100644 --- a/utilities/datasource.ts +++ b/utilities/datasource.ts @@ -127,7 +127,7 @@ export type BgTextColorPairType = keyof typeof bgTextColorPairs; export const heroOverlays = { none: 'bg-black-true/20 lg:bg-transparent', - 'black-10': 'bg-black-true/20', + 'black-10': 'bg-black-true/10', 'black-20': 'bg-black-true/20', 'black-30': 'bg-black-true/30', 'black-40': 'bg-black-true/40', From bae3ccdafbbe7a23ff611a855f0bbb64fc66ce39 Mon Sep 17 00:00:00 2001 From: Yvonne Tang <42749717+yvonnetangsu@users.noreply.github.com> Date: Tue, 13 Feb 2024 13:11:38 -0800 Subject: [PATCH 06/34] GIVCAMP-285 | Homepage theme story section (#227) * setting up component * WIP styles * new homepage story section options; add text-shadow-sm utility * Clean up --- .../SbHomepageThemeSection.styles.ts | 11 ++ .../SbHomepageThemeSection.tsx | 143 ++++++++++++++++++ .../Storyblok/SbHomepageThemeSection/index.ts | 1 + components/StoryblokProvider.tsx | 2 + tailwind.config.ts | 1 + tailwind/plugins/components/gc-text-shadow.js | 14 ++ utilities/datasource.ts | 35 +++++ 7 files changed, 207 insertions(+) create mode 100644 components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts create mode 100644 components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.tsx create mode 100644 components/Storyblok/SbHomepageThemeSection/index.ts create mode 100644 tailwind/plugins/components/gc-text-shadow.js diff --git a/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts new file mode 100644 index 00000000..6f25cc71 --- /dev/null +++ b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts @@ -0,0 +1,11 @@ +import { cnb } from 'cnbuilder'; + +export const root = 'relative overflow-hidden'; +export const bgImage = 'absolute top-0 left-0 w-full h-full object-cover'; +export const overlay = (hasBgGradient?: boolean) => cnb('absolute top-0 left-0 w-full h-full z-10', hasBgGradient ? 'bg-gradient-to-t' : ''); +export const header = 'relative overflow-hidden cc 3xl:px-100 4xl:px-[calc((100%-1800px)/2)] z-20'; +export const superhead = 'text-shadow-sm'; +export const heading = 'mb-0 whitespace-pre-line'; +export const introWrapper = 'cc relative z-20'; +export const intro = 'intro-text *:leading-display *:md:leading-cozy *:text-shadow-sm rs-mt-7 max-w-1000'; +export const contentWrapper = 'relative z-20'; diff --git a/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.tsx b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.tsx new file mode 100644 index 00000000..b6d7337a --- /dev/null +++ b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.tsx @@ -0,0 +1,143 @@ +import { cnb } from 'cnbuilder'; +import { AnimateInView } from '@/components/Animate'; +import { storyblokEditable, type SbBlokData } from '@storyblok/react/rsc'; +import { type StoryblokRichtext } from 'storyblok-rich-text-react-renderer-ts'; +import { CreateBloks } from '@/components/CreateBloks'; +import { Heading, SrOnlyText, Text } from '@/components/Typography'; +import { Container } from '@/components/Container'; +import { RichText } from '@/components/RichText'; +import { type SbImageType } from '../Storyblok.types'; +import { getProcessedImage } from '@/utilities/getProcessedImage'; +import { hasRichText } from '@/utilities/hasRichText'; +import * as styles from './SbHomepageThemeSection.styles'; +import { + bgBlurs, type BgBlurType, gradientFroms, type GradientFromType, gradientTos, type GradientToType, +} from '@/utilities/datasource'; + +type SbHomepageThemeSectionProps = { + blok: { + _uid: string; + superhead?: string; + heading?: string; + intro?: StoryblokRichtext; + content?: SbBlokData[]; + bgImage?: SbImageType; + bgBlur?: BgBlurType; + gradientTop?: GradientToType; + gradientBottom?: GradientFromType; + }; +}; + +export const SbHomepageThemeSection = ({ + blok: { + superhead, + heading, + intro, + content, + bgImage: { filename, focus } = {}, + bgBlur, + gradientTop, + gradientBottom, + }, + blok, +}: SbHomepageThemeSectionProps) => { + const hasBgGradient = !!gradientTop && !!gradientBottom; + + return ( + + {filename && ( + <> + + + + + + + + {(bgBlur !== 'none' || hasBgGradient) && ( +
+ )} + + )} + + {superhead && ( + + {superhead} + + )} + {heading && ( + + {superhead && {`${superhead}:`}}{heading} + + )} + + {hasRichText(intro) && ( + + + + )} + + + + + ); +}; diff --git a/components/Storyblok/SbHomepageThemeSection/index.ts b/components/Storyblok/SbHomepageThemeSection/index.ts new file mode 100644 index 00000000..e002ac36 --- /dev/null +++ b/components/Storyblok/SbHomepageThemeSection/index.ts @@ -0,0 +1 @@ +export * from './SbHomepageThemeSection'; diff --git a/components/StoryblokProvider.tsx b/components/StoryblokProvider.tsx index 3c47df94..3f58b641 100644 --- a/components/StoryblokProvider.tsx +++ b/components/StoryblokProvider.tsx @@ -11,6 +11,7 @@ import { SbGrid } from './Storyblok/SbGrid'; import { SbGridAlternating } from './Storyblok/SbGridAlternating'; import { SbFeatureMasonry } from './Storyblok/SbFeatureMasonry'; import { SbHomepageMvp } from './Storyblok/SbHomepageMvp'; +import { SbHomepageThemeSection } from './Storyblok/SbHomepageThemeSection'; import { SbInitiativeCard } from './Storyblok/SbInitiativeCard'; import { SbQuote } from './Storyblok/SbQuote'; import { SbScrollytelling } from './Storyblok/SbScrollytelling'; @@ -39,6 +40,7 @@ export const components = { sbGridAlternating: SbGridAlternating, sbFeatureMasonry: SbFeatureMasonry, sbHomepageMvp: SbHomepageMvp, + sbHomepageThemeSection: SbHomepageThemeSection, sbInitiativeCard: SbInitiativeCard, sbQuote: SbQuote, sbScrollytelling: SbScrollytelling, diff --git a/tailwind.config.ts b/tailwind.config.ts index b2153464..0439e888 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -30,5 +30,6 @@ export default { require('@tailwindcss/container-queries'), require(`${dir}/base/gc-base.js`)(), require(`${dir}/components/gc-typography.js`)(), + require(`${dir}/components/gc-text-shadow.js`)(), ], } satisfies Config; diff --git a/tailwind/plugins/components/gc-text-shadow.js b/tailwind/plugins/components/gc-text-shadow.js new file mode 100644 index 00000000..421316f8 --- /dev/null +++ b/tailwind/plugins/components/gc-text-shadow.js @@ -0,0 +1,14 @@ +/** + * Text shadow styles + */ +module.exports = function () { + return function ({ addComponents }) { + const components = { + '.text-shadow-sm': { + textShadow: 'rgba(0, 0, 0, 20%) 0 0 18px, rgba(0, 0, 0, 60%) 0 0 2px', + }, + }; + + addComponents(components); + }; +}; diff --git a/utilities/datasource.ts b/utilities/datasource.ts index 3953ec46..98f70273 100644 --- a/utilities/datasource.ts +++ b/utilities/datasource.ts @@ -58,6 +58,41 @@ export const accentTextColors = { }; export type AccentTextColorType = AccentColorType; +export const bgBlurs = { + none: '', + 4: 'backdrop-blur-sm', + 8: 'backdrop-blur', + 12: 'backdrop-blur-md', + 16: 'backdrop-blur-lg', +}; +export type BgBlurType = keyof typeof bgBlurs; + +export const gradientTos = { + transparent: '', + 'black-10': 'to-black-true/10', + 'black-20': 'to-black-true/20', + 'black-30': 'to-black-true/30', + 'black-40': 'to-black-true/40', + 'black-50': 'to-black-true/50', + 'black-60': 'to-black-true/60', + 'black-70': 'to-black-true/70', +}; +export type GradientToType = keyof typeof gradientTos; + +export const gradientFroms = { + 'black-10': 'from-black-true/10', + 'black-20': 'from-black-true/20', + 'black-30': 'from-black-true/30', + 'black-40': 'from-black-true/40', + 'black-50': 'from-black-true/50', + 'black-60': 'from-black-true/60', + 'black-70': 'from-black-true/70', + 'black-80': 'from-black-true/80', + 'black-90': 'from-black-true/90', + 'gc-black': 'from-gc-black', +}; +export type GradientFromType = keyof typeof gradientFroms; + export const imageAspectRatios = { '1x1': 'aspect-w-1 aspect-h-1', '1x2': 'aspect-w-1 aspect-h-2', From e2eea9deb4f98230f2bea3761f6a8df4559969fc Mon Sep 17 00:00:00 2001 From: Yvonne Tang <42749717+yvonnetangsu@users.noreply.github.com> Date: Thu, 15 Feb 2024 15:34:08 -0800 Subject: [PATCH 07/34] GIVCAMP-288 | story card horizontal variant (#228) * horizontal card styles * horizontal card styles responsive * fixup --- components/StoryCard/StoryCard.styles.tsx | 35 +++++- components/StoryCard/StoryCard.tsx | 141 ++++++++++++---------- components/Storyblok/SbStoryCard.tsx | 3 + 3 files changed, 110 insertions(+), 69 deletions(-) diff --git a/components/StoryCard/StoryCard.styles.tsx b/components/StoryCard/StoryCard.styles.tsx index cb5e468b..2f295a4d 100644 --- a/components/StoryCard/StoryCard.styles.tsx +++ b/components/StoryCard/StoryCard.styles.tsx @@ -1,15 +1,35 @@ import { cnb } from 'cnbuilder'; -export const root = '@container relative z-10 max-w-[32rem] sm:max-w-400 md:max-w-full mx-auto'; - -export const cardWrapper = 'relative group @200:text-15 @250:text-17 @280:!type-0 @md:!text-26'; +export const root = (isHorizontal: boolean) => cnb( + '@container relative z-10 mx-auto', { + 'max-w-300 sm:max-w-400 md:max-w-full': !isHorizontal, + 'max-w-700 lg:max-w-none': isHorizontal, + }, +); + +export const cardWrapper = (isHorizontal: boolean) => cnb( + 'relative group', { + 'grid lg:grid-cols-2 bg-black-true/50': isHorizontal, + '@200:text-15 @250:text-17 @280:!type-0 @md:!text-26': !isHorizontal, + }, +); export const imageWrapper = 'transition-all aspect-w-1 aspect-h-1 overflow-hidden'; export const image = 'object-cover w-full h-full group-hocus-within:scale-105 transition-transform'; -export const heading = (hasTabColor: boolean) => cnb('mt-06em rs-mb-neg1 text-current pr-08em xl:pr-1em pl-12 xl:pl-21 border-l-[1.2rem] xl:border-l-[1.8rem]', { - '@200:border-l-[1.2rem] @xs:border-l-[1.8rem] @200:pl-12 @xs:pl-21 @200:pr-08em @320:pr-1em': hasTabColor, +export const contentWrapper = (isHorizontal: boolean) => cnb({ + 'rs-pr-4 rs-py-4': isHorizontal, +}); +export const heading = (hasTabColor: boolean, isHorizontal: boolean, isSmallHeading: boolean) => cnb('text-current', { + 'border-l-[1.2rem] xl:border-l-[1.8rem] @200:border-l-[1.2rem] @xs:border-l-[1.8rem]': hasTabColor, + '@200:pl-12 @xs:pl-21 @200:pr-08em @320:pr-1em': hasTabColor && !isHorizontal, + 'mt-06em rs-mb-neg1 pr-08em xl:pr-1em pl-12 xl:pl-21': !isHorizontal, + 'rs-pb-2 mb-0 rs-pl-2': isHorizontal, + 'type-3': !isHorizontal && !isSmallHeading, + 'type-2': !isHorizontal && isSmallHeading, + 'fluid-type-4 xl:fluid-type-5': isHorizontal && !isSmallHeading, + 'fluid-type-3 xl:fluid-type-4': isHorizontal && isSmallHeading, }); export const headingLink = 'stretched-link no-underline !font-bold !leading-tight'; @@ -20,4 +40,7 @@ export const taxonomy = (hasTabColor: boolean) => cnb('list-unstyled leading-dis export const taxonomyItem = 'inline-block mb-0'; -export const body = 'pl-12 xl:pl-21 @200:pl-12 @xs:pl-21 pr-08em xl:pr-1em @200:pr-08em @320:pr-1em ml-12 xl:ml-18 @200:ml-12 @xs:ml-18'; +export const body = (isHorizontal: boolean) => cnb('', { + 'border-l-[1.2rem] xl:border-l-[1.8rem] @200:border-l-[1.2rem] @xs:border-l-[1.8rem] rs-pl-2' : isHorizontal, + 'pl-12 xl:pl-21 @200:pl-12 @xs:pl-21 pr-08em xl:pr-1em @200:pr-08em @320:pr-1em ml-12 xl:ml-18 @200:ml-12 @xs:ml-18': !isHorizontal, +}); diff --git a/components/StoryCard/StoryCard.tsx b/components/StoryCard/StoryCard.tsx index e27fb2fe..fc8a7333 100644 --- a/components/StoryCard/StoryCard.tsx +++ b/components/StoryCard/StoryCard.tsx @@ -1,12 +1,14 @@ import { cnb } from 'cnbuilder'; import { AnimateInView, type AnimationType } from '../Animate'; import { CtaLink } from '../Cta/CtaLink'; -import { Heading, type HeadingType, Paragraph } from '../Typography'; +import { + Heading, type HeadingType, Paragraph, type FontSizeType, +} from '../Typography'; import { SbLinkType } from '../Storyblok/Storyblok.types'; import { getProcessedImage } from '@/utilities/getProcessedImage'; -import { slugify } from '@/utilities/slugify'; import { accentBorderColors, type AccentBorderColorType } from '@/utilities/datasource'; import * as styles from './StoryCard.styles'; +import { FlexBox } from '../FlexBox'; export type StoryCardProps = React.HTMLAttributes & { heading?: string; @@ -21,6 +23,7 @@ export type StoryCardProps = React.HTMLAttributes & { taxonomy?: string[]; animation?: AnimationType; delay?: number; + isHorizontal?: boolean; }; export const StoryCard = ({ @@ -36,67 +39,79 @@ export const StoryCard = ({ taxonomy, animation = 'none', delay, + isHorizontal, className, ...props -}: StoryCardProps) => ( - -
-
- {imageSrc && ( -
- - - - - - -
- )} - {heading && ( - { + let headingSize: FontSizeType = 3; + if (isHorizontal) { + headingSize = 'f5'; + } else if (isSmallHeading && !isHorizontal) { + headingSize = 2; + }; + + return ( + +
+
+ {imageSrc && ( +
+ + + + + + +
+ )} + - - {heading} - - - )} - {body && ( - {body} - )} -
- {/* No taxonomy for MVP; display max 3 topic tags */} - {/* {!!taxonomy?.length && ( -
    - {taxonomy.slice(0, 3).map((item) => ( -
  • - {item} -
  • - ))} -
- )} */} -
-
-); + {heading && ( + + + {heading} + + + )} + {body && ( + + {body} + + )} + +
+
+
+ ); +}; diff --git a/components/Storyblok/SbStoryCard.tsx b/components/Storyblok/SbStoryCard.tsx index 9c4206aa..eb786961 100644 --- a/components/Storyblok/SbStoryCard.tsx +++ b/components/Storyblok/SbStoryCard.tsx @@ -31,6 +31,7 @@ export type SbStoryCardProps = { link?: SbLinkType; animation?: AnimationType; delay?: number; + isHorizontal?: boolean; }; }; @@ -58,6 +59,7 @@ export const SbStoryCard = ({ link, animation, delay, + isHorizontal, }, blok, }: SbStoryCardProps) => ( @@ -75,5 +77,6 @@ export const SbStoryCard = ({ animation={animation} delay={delay} taxonomy={topics} + isHorizontal={isHorizontal} /> ); From b579c1f5428a1639a8485fa785876f3a088879d9 Mon Sep 17 00:00:00 2001 From: Yvonne Tang <42749717+yvonnetangsu@users.noreply.github.com> Date: Thu, 15 Feb 2024 16:04:25 -0800 Subject: [PATCH 08/34] Larger image crop for horizontal card variant (#229) --- components/StoryCard/StoryCard.tsx | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/components/StoryCard/StoryCard.tsx b/components/StoryCard/StoryCard.tsx index fc8a7333..96ba28d9 100644 --- a/components/StoryCard/StoryCard.tsx +++ b/components/StoryCard/StoryCard.tsx @@ -60,24 +60,26 @@ export const StoryCard = ({ {imageSrc && (
+ {!isHorizontal && ( + + )} - From 37fc3648437999d79ddce55595064d5d25f810db Mon Sep 17 00:00:00 2001 From: Github Action Date: Fri, 16 Feb 2024 22:35:28 +0000 Subject: [PATCH 09/34] 1.1.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8f6d8c1e..be2242c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ood-giving-campaign", - "version": "1.0.3", + "version": "1.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ood-giving-campaign", - "version": "1.0.3", + "version": "1.1.0", "dependencies": { "@heroicons/react": "^2.1.1", "@storyblok/react": "^3.0.8", diff --git a/package.json b/package.json index 370de7fb..c2789514 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ood-giving-campaign", - "version": "1.0.3", + "version": "1.1.0", "description": "Momentum", "author": "Stanford University", "keywords": [ From 75997145c612f267bd5c6d06ab602f6dfc89dac0 Mon Sep 17 00:00:00 2001 From: Yvonne Tang <42749717+yvonnetangsu@users.noreply.github.com> Date: Tue, 20 Feb 2024 13:36:41 -0800 Subject: [PATCH 10/34] GIVCAMP-291 | Initiative card update (#231) * Remove unused prop * link text and different icons * Use switch instead * Add SrOnly text for internal links * Smaller image --- components/Cta/Cta.types.ts | 2 +- components/HeroIcon/HeroIcon.styles.tsx | 2 + .../InitiativeCard/InitiativeCard.styles.ts | 9 +- components/InitiativeCard/InitiativeCard.tsx | 146 +++++++++++------- components/Storyblok/SbInitiativeCard.tsx | 4 +- components/TextCard/TextCard.tsx | 2 +- 6 files changed, 105 insertions(+), 60 deletions(-) diff --git a/components/Cta/Cta.types.ts b/components/Cta/Cta.types.ts index ecdf98eb..ab3162ea 100644 --- a/components/Cta/Cta.types.ts +++ b/components/Cta/Cta.types.ts @@ -40,6 +40,6 @@ export interface CtaCommonProps { icon?: IconType; iconPosition?: 'left' | 'right'; animate?: IconAnimationType; - iconProps?: HeroIconProps & React.ComponentProps<'svg'>; + iconProps?: Omit & React.ComponentProps<'svg'>; children?: React.ReactNode; } diff --git a/components/HeroIcon/HeroIcon.styles.tsx b/components/HeroIcon/HeroIcon.styles.tsx index 8bc90191..6a186bdd 100644 --- a/components/HeroIcon/HeroIcon.styles.tsx +++ b/components/HeroIcon/HeroIcon.styles.tsx @@ -2,6 +2,7 @@ import { ArrowPathIcon, ArrowUpIcon, ArrowDownIcon, + ArrowDownTrayIcon, ArrowLeftIcon, ArrowRightIcon, ArrowUpRightIcon, @@ -34,6 +35,7 @@ export const iconMap = { 'chevron-down': ChevronDownIcon, 'chevron-right': ChevronRightIcon, 'chevron-up': ChevronUpIcon, + download: ArrowDownTrayIcon, 'triangle-down': PlayIcon, 'triangle-right': PlayIcon, 'triangle-up': PlayIcon, diff --git a/components/InitiativeCard/InitiativeCard.styles.ts b/components/InitiativeCard/InitiativeCard.styles.ts index 2bb1844c..353834bf 100644 --- a/components/InitiativeCard/InitiativeCard.styles.ts +++ b/components/InitiativeCard/InitiativeCard.styles.ts @@ -16,6 +16,9 @@ export const body = (hasTabColor: boolean) => cnb('rs-pl-1 text-current', { 'border-l-[1.4rem] md:border-l-[2rem]': hasTabColor, }); -export const cta = 'inline-block bg-gc-black text-white hocus:text-white stretched-link no-underline rs-py-1 rs-pr-1'; - -export const arrowIcon = 'inline-block mb-0 mt-auto w-34 ml-auto mr-0 group-hover:translate-x-03em'; +export const cta = 'group/cta inline-block bg-gc-black text-white hocus:text-white stretched-link no-underline hocus:no-underline rs-py-1 rs-pr-1'; +export const linkText = 'text-19 md:text-25 mr-0 ml-auto last:children:underline'; +export const lastword = 'underline decoration-digital-red-light underline-offset-4 group-hocus/cta:decoration-white'; +export const icon = (hasLinkText?: boolean) => cnb('inline-block mb-0 mt-auto w-20 md:w-24 mr-0', + hasLinkText? 'ml-10' : 'ml-auto', +); diff --git a/components/InitiativeCard/InitiativeCard.tsx b/components/InitiativeCard/InitiativeCard.tsx index d10e9a60..7678bcfc 100644 --- a/components/InitiativeCard/InitiativeCard.tsx +++ b/components/InitiativeCard/InitiativeCard.tsx @@ -1,23 +1,25 @@ import { HTMLAttributes } from 'react'; import { cnb } from 'cnbuilder'; import { AnimateInView, type AnimationType } from '../Animate'; -import { CtaLink } from '../Cta/CtaLink'; -import { Heading, type HeadingType, Paragraph } from '../Typography'; -import { HeroIcon } from '../HeroIcon'; +import { CtaLink, type IconAnimationType } from '../Cta'; +import { + Heading, type HeadingType, Paragraph, Text, SrOnlyText, +} from '../Typography'; import { FlexBox } from '../FlexBox'; import { type SbLinkType } from '../Storyblok/Storyblok.types'; import { getProcessedImage } from '@/utilities/getProcessedImage'; import { accentBorderColors, type AccentBorderColorType } from '@/utilities/datasource'; import * as styles from './InitiativeCard.styles'; +import { IconType } from '../HeroIcon'; export type InitiativeCardProps = HTMLAttributes & { heading?: string; headingLevel?: HeadingType; - isSmallHeading?: boolean; body?: string; imageSrc?: string; imageFocus?: string; tabColor?: AccentBorderColorType; + linkText?: string; link?: SbLinkType; animation?: AnimationType; delay?: number; @@ -26,64 +28,100 @@ export type InitiativeCardProps = HTMLAttributes & { export const InitiativeCard = ({ heading, headingLevel = 'h2', - isSmallHeading, body, imageSrc = '', imageFocus, tabColor, + linkText, link, animation = 'none', delay, className, ...props -}: InitiativeCardProps) => ( - - -
-
- +}: InitiativeCardProps) => { + // Split the linkText into an array of words + const words = linkText?.trim().split(/\s+/); + + // Extract the last word + const lastWord = words?.pop(); + + // Join the remaining words to form the first part of the link text + const firstPart = words?.join(' '); + + let cardIcon: IconType; + let iconAnimation: IconAnimationType; + + switch (link?.linktype) { + case 'asset': + cardIcon = 'download'; + iconAnimation = 'down'; + break; + case 'story': + cardIcon = 'arrow-right'; + iconAnimation = 'right'; + break; + default: + cardIcon = 'external'; + iconAnimation = 'top-right'; + } + + return ( + + +
+
+ +
+ + {heading} +
- - {heading} - -
-
- + + {body} + +
+ - {body} - -
- - - -
-
-); + {linkText ? ( + + {firstPart} {lastWord} + + ) : ( + {`Go to the ${heading} page`} + )} + + + + ); +}; diff --git a/components/Storyblok/SbInitiativeCard.tsx b/components/Storyblok/SbInitiativeCard.tsx index c34a4d5f..54cb5baa 100644 --- a/components/Storyblok/SbInitiativeCard.tsx +++ b/components/Storyblok/SbInitiativeCard.tsx @@ -11,11 +11,11 @@ type SbInitiativeCardProps = { heading?: string; headingLevel?: HeadingType; body?: string; - isSmallHeading?: boolean; image?: SbImageType; tabColor?: { value?: PaletteAccentHexColorType; } + linkText?: string; link?: SbLinkType; animation?: AnimationType; delay?: number; @@ -29,6 +29,7 @@ export const SbInitiativeCard = ({ body, image: { filename, focus } = {}, tabColor: { value } = {}, + linkText, link, animation, delay, @@ -43,6 +44,7 @@ export const SbInitiativeCard = ({ imageSrc={filename} imageFocus={focus} tabColor={paletteAccentColors[value]} + linkText={linkText} link={link} animation={animation} delay={delay} diff --git a/components/TextCard/TextCard.tsx b/components/TextCard/TextCard.tsx index b9d02c77..032a33f1 100644 --- a/components/TextCard/TextCard.tsx +++ b/components/TextCard/TextCard.tsx @@ -56,7 +56,7 @@ export const TextCard = ({ From bdf1dcd6f01dfb269b38a070bfd6221bf33face7 Mon Sep 17 00:00:00 2001 From: Yvonne Tang <42749717+yvonnetangsu@users.noreply.github.com> Date: Thu, 22 Feb 2024 11:08:55 -0800 Subject: [PATCH 11/34] GIVCAMP-286 | Section component new options (#232) * Section header options * Section options; changemaker card text color always set to white fixup * Responsive font size * Add faint text shadow to small text in story heroes * Clean up --- .../BlurryPoster/BlurryPoster.styles.tsx | 4 +- components/BlurryPoster/BlurryPoster.tsx | 1 + .../ChangemakerCard/ChangemakerCard.tsx | 3 +- components/Hero/BasicHeroMvp.tsx | 2 +- .../SbHomepageThemeSection.styles.ts | 2 +- .../SbHomepageThemeSection.tsx | 1 - .../Storyblok/SbSection/SbSection.styles.ts | 38 +++++++++ .../Storyblok/{ => SbSection}/SbSection.tsx | 80 +++++++++---------- components/Storyblok/SbSection/index.ts | 1 + components/StoryblokProvider.tsx | 52 ++++++------ 10 files changed, 110 insertions(+), 74 deletions(-) create mode 100644 components/Storyblok/SbSection/SbSection.styles.ts rename components/Storyblok/{ => SbSection}/SbSection.tsx (67%) create mode 100644 components/Storyblok/SbSection/index.ts diff --git a/components/BlurryPoster/BlurryPoster.styles.tsx b/components/BlurryPoster/BlurryPoster.styles.tsx index cc17dabb..932ff7b5 100644 --- a/components/BlurryPoster/BlurryPoster.styles.tsx +++ b/components/BlurryPoster/BlurryPoster.styles.tsx @@ -34,7 +34,7 @@ export const contentWrapper = ( 'lg:order-first': !imageOnLeft && isTwoCol, }); -export const superhead = (imageOnLeft?: boolean, isTwoCol?: boolean) => cnb('cc rs-mb-1 w-full', { +export const superhead = (imageOnLeft?: boolean, isTwoCol?: boolean) => cnb('cc rs-mb-1 w-full text-shadow-sm', { 'lg:pl-40 2xl:pl-60 3xl:pr-[calc(100%-750px)]': imageOnLeft && isTwoCol, 'lg:pr-40 2xl:pr-60 3xl:pl-[calc(100%-750px)]': !imageOnLeft && isTwoCol, }); @@ -92,7 +92,7 @@ export const bodyWrapper = (imageOnLeft?: boolean, isTwoCol?: boolean) => cnb('c '3xl:pl-[calc(100%-750px)] lg:pr-40 2xl:pr-60': !imageOnLeft && isTwoCol, '*:max-w-[50ch]': !isTwoCol, }); - +export const dek = 'text-shadow-sm'; export const cta = 'rs-mt-4'; export const imageWrapper = (imageOnLeft?: boolean, isTwoCol?: boolean, hasImage?: boolean) => cnb('w-full cc', { diff --git a/components/BlurryPoster/BlurryPoster.tsx b/components/BlurryPoster/BlurryPoster.tsx index f856e1b5..82ab4356 100644 --- a/components/BlurryPoster/BlurryPoster.tsx +++ b/components/BlurryPoster/BlurryPoster.tsx @@ -197,6 +197,7 @@ export const BlurryPoster = ({ variant="overview" weight="normal" leading="display" + className={styles.dek} > {body} diff --git a/components/ChangemakerCard/ChangemakerCard.tsx b/components/ChangemakerCard/ChangemakerCard.tsx index d4ad81c7..5138ca98 100644 --- a/components/ChangemakerCard/ChangemakerCard.tsx +++ b/components/ChangemakerCard/ChangemakerCard.tsx @@ -97,13 +97,14 @@ export const ChangemakerCard = ({ size={2} leading="tight" align="center" + color="white" className={styles.heading} > {heading} )} {subheading && ( - {subheading} + {subheading} )}
diff --git a/components/Hero/BasicHeroMvp.tsx b/components/Hero/BasicHeroMvp.tsx index f51ac484..7621dd7a 100644 --- a/components/Hero/BasicHeroMvp.tsx +++ b/components/Hero/BasicHeroMvp.tsx @@ -46,7 +46,7 @@ export const BasicHeroMvp = ({ align="center" leading="tight" color="white" - className="relative z-10 max-w-1200 mx-auto fluid-type-5 md:fluid-type-7 mb-0" + className="relative z-10 max-w-1200 mx-auto fluid-type-6 md:fluid-type-7 mb-0 text-balance" > {title} diff --git a/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts index 6f25cc71..f2f9ae77 100644 --- a/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts +++ b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts @@ -5,7 +5,7 @@ export const bgImage = 'absolute top-0 left-0 w-full h-full object-cover'; export const overlay = (hasBgGradient?: boolean) => cnb('absolute top-0 left-0 w-full h-full z-10', hasBgGradient ? 'bg-gradient-to-t' : ''); export const header = 'relative overflow-hidden cc 3xl:px-100 4xl:px-[calc((100%-1800px)/2)] z-20'; export const superhead = 'text-shadow-sm'; -export const heading = 'mb-0 whitespace-pre-line'; +export const heading = 'fluid-type-8 md:gc-splash mb-0 whitespace-pre-line'; export const introWrapper = 'cc relative z-20'; export const intro = 'intro-text *:leading-display *:md:leading-cozy *:text-shadow-sm rs-mt-7 max-w-1000'; export const contentWrapper = 'relative z-20'; diff --git a/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.tsx b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.tsx index b6d7337a..0823cde2 100644 --- a/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.tsx +++ b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.tsx @@ -116,7 +116,6 @@ export const SbHomepageThemeSection = ({ {heading && ( cnb('relative z-10', headerAlign === 'right' ? 'mr-0 ml-auto' : 'ml-0'); +export const bar = (headerAlign?: AlignType) => cnb( + 'block w-10 sm:w-14 md:w-20 lg:w-30 xl:w-40', { + 'order-first': headerAlign === 'left', + 'order-last': headerAlign === 'right', + }, +); +export const headerContent = (hasBarColor: boolean, hasSuperhead: boolean, headerAlign?: AlignType) => cnb( + 'cc whitespace-pre-line w-full 3xl:max-w-[90%]', { + '-ml-10 sm:-ml-14 md:-ml-20 lg:-ml-30 xl:-ml-40': hasBarColor && headerAlign !== 'right' && headerAlign !== 'center', + '-mr-10 sm:-mr-14 md:-mr-20 lg:-mr-30 xl:-mr-40': hasBarColor && headerAlign === 'right', + 'ml-0': !hasBarColor && headerAlign === 'left', + 'mr-0': !hasBarColor && headerAlign === 'right', + '-mt-05em' : !hasSuperhead, +}); +export const heading = (isSerifHeader: boolean, isSmallHeading: boolean, headerAlign?: AlignType ) => cnb( + 'mb-0', { + 'text-balance mx-auto max-w-1000': headerAlign === 'center', + 'fluid-type-8 md:gc-splash': !isSerifHeader && !isSmallHeading, + 'fluid-type-8': !isSerifHeader && isSmallHeading, + 'fluid-type-6 md:fluid-type-7': isSerifHeader && !isSmallHeading, + 'fluid-type-6': isSerifHeader && isSmallHeading, +}); +export const subhead = (headerAlign?: AlignType) => cnb('relative z-10 rs-mt-3 ', { + 'mr-0 ml-auto': headerAlign === 'right', + 'mx-auto max-w-800': headerAlign === 'center', + 'max-w-prose': headerAlign !== 'center', +}); +export const contentWrapper = 'relative z-10'; +export const caption = 'caption *:leading-display mt-08em max-w-prose-wide'; diff --git a/components/Storyblok/SbSection.tsx b/components/Storyblok/SbSection/SbSection.tsx similarity index 67% rename from components/Storyblok/SbSection.tsx rename to components/Storyblok/SbSection/SbSection.tsx index 162b6e10..a5e54e6e 100644 --- a/components/Storyblok/SbSection.tsx +++ b/components/Storyblok/SbSection/SbSection.tsx @@ -5,24 +5,25 @@ import { cnb } from 'cnbuilder'; import { useScroll, m, useTransform } from 'framer-motion'; import { storyblokEditable, type SbBlokData } from '@storyblok/react/rsc'; import { type StoryblokRichtext } from 'storyblok-rich-text-react-renderer-ts'; -import { CreateBloks } from '../CreateBloks'; -import { FlexBox } from '../FlexBox'; +import { CreateBloks } from '@/components/CreateBloks'; +import { FlexBox } from '@/components/FlexBox'; import { Heading, type HeadingType, SrOnlyText, Text, Paragraph, -} from '../Typography'; -import { Container, type BgColorType } from '../Container'; -import { ImageOverlay } from '../ImageOverlay'; -import { RichText } from '../RichText'; -import { WidthBox } from '../WidthBox'; +} from '@/components/Typography'; +import { Container, type BgColorType } from '@/components/Container'; +import { ImageOverlay } from '@/components/ImageOverlay'; +import { RichText } from '@/components/RichText'; +import { WidthBox } from '@/components/WidthBox'; import { accentBgColors, type PaddingType, type MarginType } from '@/utilities/datasource'; import { paletteAccentColors, type PaletteAccentHexColorType } from '@/utilities/colorPalettePlugin'; -import { type SbImageType, type SbColorStopProps } from './Storyblok.types'; +import { type SbImageType, type SbColorStopProps } from '../Storyblok.types'; import { getProcessedImage } from '@/utilities/getProcessedImage'; import { hasRichText } from '@/utilities/hasRichText'; +import * as styles from './SbSection.styles'; type SbSectionProps = { blok: { @@ -30,12 +31,13 @@ type SbSectionProps = { content?: SbBlokData[]; superhead?: string; heading?: string; + headerAlign?: styles.AlignType; isSmallHeading?: boolean; headingLevel?: HeadingType; + isSerifHeader?: boolean; subheading?: string; caption?: StoryblokRichtext; captionColumnWidth?: '12' | '10' | '8' | '6' | '4'; - rightAlignHeader?: boolean; barColor?: { value?: PaletteAccentHexColorType; } @@ -54,12 +56,13 @@ export const SbSection = ({ content, superhead, heading, + headerAlign, isSmallHeading, + isSerifHeader, headingLevel, subheading, caption, captionColumnWidth, - rightAlignHeader, barColor: { value: barColorValue } = {}, bgColor, bgImage: { filename, focus } = {}, @@ -104,10 +107,11 @@ export const SbSection = ({ return ( {/* Add background color animation if there are at least 2 color stops */} @@ -117,37 +121,29 @@ export const SbSection = ({ bgColor={bgColor} pt={paddingTop} pb={paddingBottom} - className="relative overflow-hidden" + className={styles.wrapper} > {filename && ( - + )} {(heading || superhead) && ( - - {barColorValue && ( -
- )} -
+ {barColorValue && headerAlign !== 'center' && ( +
)} - > +
{superhead && ( {superhead} @@ -156,12 +152,11 @@ export const SbSection = ({ {heading && ( {superhead && {`${superhead}:`}}{heading} @@ -173,17 +168,18 @@ export const SbSection = ({ {subheading} )} - + @@ -193,7 +189,7 @@ export const SbSection = ({ )} diff --git a/components/Storyblok/SbSection/index.ts b/components/Storyblok/SbSection/index.ts new file mode 100644 index 00000000..01d1cfbb --- /dev/null +++ b/components/Storyblok/SbSection/index.ts @@ -0,0 +1 @@ +export * from './SbSection'; diff --git a/components/StoryblokProvider.tsx b/components/StoryblokProvider.tsx index 3f58b641..1483dc4c 100644 --- a/components/StoryblokProvider.tsx +++ b/components/StoryblokProvider.tsx @@ -1,31 +1,31 @@ 'use client'; import { storyblokInit, apiPlugin } from '@storyblok/react/rsc'; -import { SbBanner } from './Storyblok/SbBanner'; -import { SbBasicPage } from './Storyblok/SbBasicPage'; -import { SbBlurryPoster } from './Storyblok/SbBlurryPoster'; -import { SbCardWysiwyg } from './Storyblok/SbCardWysiwyg'; -import { SbChangemakerCard } from './Storyblok/SbChangemakerCard'; -import { SbCta } from './Storyblok/SbCta'; -import { SbEmbedMedia } from './Storyblok/SbEmbedMedia'; -import { SbGrid } from './Storyblok/SbGrid'; -import { SbGridAlternating } from './Storyblok/SbGridAlternating'; -import { SbFeatureMasonry } from './Storyblok/SbFeatureMasonry'; -import { SbHomepageMvp } from './Storyblok/SbHomepageMvp'; -import { SbHomepageThemeSection } from './Storyblok/SbHomepageThemeSection'; -import { SbInitiativeCard } from './Storyblok/SbInitiativeCard'; -import { SbQuote } from './Storyblok/SbQuote'; -import { SbScrollytelling } from './Storyblok/SbScrollytelling'; -import { SbSection } from './Storyblok/SbSection'; -import { SbSidebarCard } from './Storyblok/SbSidebarCard'; -import { SbStoryMvp } from './Storyblok/SbStoryMvp/SbStoryMvp'; -import { SbStoryCard } from './Storyblok/SbStoryCard'; -import { SbStoryImage } from './Storyblok/SbStoryImage'; -import { SbText } from './Storyblok/SbText'; -import { SbTextCard } from './Storyblok/SbTextCard'; -import { SbTexturedBar } from './Storyblok/SbTexturedBar'; -import { SbTriangle } from './Storyblok/SbTriangle'; -import { SbTypeform } from './Storyblok/SbTypeform'; -import { SbWysiwyg } from './Storyblok/SbWysiwyg'; +import { SbBanner } from '@/components/Storyblok/SbBanner'; +import { SbBasicPage } from '@/components/Storyblok/SbBasicPage'; +import { SbBlurryPoster } from '@/components/Storyblok/SbBlurryPoster'; +import { SbCardWysiwyg } from '@/components/Storyblok/SbCardWysiwyg'; +import { SbChangemakerCard } from '@/components/Storyblok/SbChangemakerCard'; +import { SbCta } from '@/components/Storyblok/SbCta'; +import { SbEmbedMedia } from '@/components/Storyblok/SbEmbedMedia'; +import { SbGrid } from '@/components/Storyblok/SbGrid'; +import { SbGridAlternating } from '@/components/Storyblok/SbGridAlternating'; +import { SbFeatureMasonry } from '@/components/Storyblok/SbFeatureMasonry'; +import { SbHomepageMvp } from '@/components/Storyblok/SbHomepageMvp'; +import { SbHomepageThemeSection } from '@/components/Storyblok/SbHomepageThemeSection'; +import { SbInitiativeCard } from '@/components/Storyblok/SbInitiativeCard'; +import { SbQuote } from '@/components/Storyblok/SbQuote'; +import { SbScrollytelling } from '@/components/Storyblok/SbScrollytelling'; +import { SbSection } from '@/components/Storyblok/SbSection'; +import { SbSidebarCard } from '@/components/Storyblok/SbSidebarCard'; +import { SbStoryMvp } from '@/components/Storyblok/SbStoryMvp/SbStoryMvp'; +import { SbStoryCard } from '@/components/Storyblok/SbStoryCard'; +import { SbStoryImage } from '@/components/Storyblok/SbStoryImage'; +import { SbText } from '@/components/Storyblok/SbText'; +import { SbTextCard } from '@/components/Storyblok/SbTextCard'; +import { SbTexturedBar } from '@/components/Storyblok/SbTexturedBar'; +import { SbTriangle } from '@/components/Storyblok/SbTriangle'; +import { SbTypeform } from '@/components/Storyblok/SbTypeform'; +import { SbWysiwyg } from '@/components/Storyblok/SbWysiwyg'; import ComponentNotFound from '@/components/Storyblok/ComponentNotFound'; export const components = { From 713e565224e83a507ad33296650ef7b765d854ca Mon Sep 17 00:00:00 2001 From: Github Action Date: Thu, 22 Feb 2024 20:49:33 +0000 Subject: [PATCH 12/34] 1.1.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index be2242c6..ea9a654b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ood-giving-campaign", - "version": "1.1.0", + "version": "1.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ood-giving-campaign", - "version": "1.1.0", + "version": "1.1.1", "dependencies": { "@heroicons/react": "^2.1.1", "@storyblok/react": "^3.0.8", diff --git a/package.json b/package.json index c2789514..f7e31f10 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ood-giving-campaign", - "version": "1.1.0", + "version": "1.1.1", "description": "Momentum", "author": "Stanford University", "keywords": [ From a73f6d85050451c3578214eb47427426e1532eb5 Mon Sep 17 00:00:00 2001 From: Yvonne Tang <42749717+yvonnetangsu@users.noreply.github.com> Date: Fri, 23 Feb 2024 14:34:24 -0800 Subject: [PATCH 13/34] GIVCAMP-287 | Basic page hero updates + increase editor preview valid time (#234) * Basic page hero options * Up editor token valid time to 3 hours at a time; hero padding options and other updates * Clean up styles --- app/(editor)/editor/page.tsx | 8 +- components/Hero/BasicHero.styles.ts | 21 ++++ components/Hero/BasicHero.tsx | 99 +++++++++++++++++++ components/Hero/BasicHeroMvp.tsx | 71 ------------- components/Hero/index.ts | 2 +- .../Homepage/HomepageSplitHero.styles.ts | 2 - components/Storyblok/SbBasicPage.tsx | 43 +++++--- .../SbHomepageThemeSection.styles.ts | 2 +- .../Storyblok/SbSection/SbSection.styles.ts | 8 +- 9 files changed, 157 insertions(+), 99 deletions(-) create mode 100644 components/Hero/BasicHero.styles.ts create mode 100644 components/Hero/BasicHero.tsx delete mode 100644 components/Hero/BasicHeroMvp.tsx diff --git a/app/(editor)/editor/page.tsx b/app/(editor)/editor/page.tsx index e193e9c0..d482ac4b 100644 --- a/app/(editor)/editor/page.tsx +++ b/app/(editor)/editor/page.tsx @@ -89,16 +89,16 @@ async function getStoryData({ path }: PageProps['searchParams']): Promise { const validationString = searchParams['_storyblok_tk[space_id]'] + ':' + process.env.STORYBLOK_PREVIEW_EDITOR_TOKEN + ':' + searchParams['_storyblok_tk[timestamp]']; const validationToken = crypto.createHash('sha1').update(validationString).digest('hex'); if (searchParams['_storyblok_tk[token]'] == validationToken && - Number(searchParams['_storyblok_tk[timestamp]']) > Math.floor(Date.now()/1000)-3600) { + Number(searchParams['_storyblok_tk[timestamp]']) > Math.floor(Date.now()/1000)-10800) { // you're in the edit mode. return true; } diff --git a/components/Hero/BasicHero.styles.ts b/components/Hero/BasicHero.styles.ts new file mode 100644 index 00000000..acf87dae --- /dev/null +++ b/components/Hero/BasicHero.styles.ts @@ -0,0 +1,21 @@ +import { cnb } from 'cnbuilder'; + +export const heroPaddings = { + 'balance-sm': 'py-[34vw] sm:py-[24vw] xl:py-[16vw] 3xl:py-[26rem]', + 'balance-md': 'py-[36vw] sm:py-[26vw] xl:py-[17vw] 3xl:py-[30rem]', + 'balance-lg': 'py-[40vw] sm:py-[28vw] xl:py-[19vw] 3xl:py-[36rem]', + top: 'pt-[45vw] pb-[15vw] sm:pt-[30vw] sm:pb-[12vw] xl:pt-[25vw] xl:pb-[8vw] 3xl:pt-[40rem] 3xl:pb-[14rem]', +}; +export type HeroPaddingType = keyof typeof heroPaddings; + +export const root = 'relative break-words bg-black-70'; +export const contentWrapper = '*:mx-auto'; +export const superhead = 'relative z-10 xl:max-w-900 mx-auto rs-mb-0'; +export const heading = (isDrukHeading: boolean, isSmallHeading: boolean) => cnb('relative z-10 max-w-1200 mx-auto mb-0 text-balance', { + 'fluid-type-7 md:fluid-type-8': isDrukHeading && isSmallHeading, + 'fluid-type-7 md:gc-splash': isDrukHeading && !isSmallHeading, + 'fluid-type-6 md:fluid-type-7': !isDrukHeading && isSmallHeading, + 'fluid-type-6 md:fluid-type-8': !isDrukHeading && !isSmallHeading, +}); +export const subhead = 'relative z-10 xl:max-w-900 mx-auto rs-mt-1 text-shadow-sm'; +export const content = 'rs-mt-4 w-fit'; diff --git a/components/Hero/BasicHero.tsx b/components/Hero/BasicHero.tsx new file mode 100644 index 00000000..41aa2b7a --- /dev/null +++ b/components/Hero/BasicHero.tsx @@ -0,0 +1,99 @@ +import { cnb } from 'cnbuilder'; +import { Container } from '@/components/Container'; +import { Heading, SrOnlyText, Text } from '@/components/Typography'; +import { ImageOverlay } from '@/components/ImageOverlay'; +import { getProcessedImage } from '@/utilities/getProcessedImage'; +import * as styles from './BasicHero.styles'; + +/** + * Basic page hero that allows for different hero styles (e.g., initiative landing and detailed pages) + */ +type BasicHeroProps = { + title: string; + isDrukHeading?: boolean; + isSmallHeading?: boolean; + superhead?: string; + subheading?: string; + imageSrc?: string; + imageFocus?: string; + heroContent?: React.ReactNode; + paddingType?: styles.HeroPaddingType; +}; + +export const BasicHero = ({ + title, + isDrukHeading, + isSmallHeading, + superhead, + subheading, + imageSrc, + imageFocus, + heroContent, + paddingType, +}: BasicHeroProps) => ( + + {imageSrc && ( + <> + + + + )} + + {superhead && ( + + {superhead} + + )} + + {superhead && {`${superhead}: `}}{title} + + {subheading && ( + + {subheading} + + )} + {!!heroContent && ( +
+ {heroContent} +
+ )} +
+
+); diff --git a/components/Hero/BasicHeroMvp.tsx b/components/Hero/BasicHeroMvp.tsx deleted file mode 100644 index 7621dd7a..00000000 --- a/components/Hero/BasicHeroMvp.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import { Container } from '@/components/Container'; -import { Heading, Text } from '@/components/Typography'; -import { ImageOverlay } from '@/components/ImageOverlay'; -import { getProcessedImage } from '@/utilities/getProcessedImage'; -import { subhead } from '../Scrollytelling'; - -/** - * Temporary hero for MVP basic page - */ -type BasicHeroMvpProps = { - title: string; - subheading?: string; - imageSrc?: string; - imageFocus?: string; - heroContent?: React.ReactNode; -}; - -export const BasicHeroMvp = ({ - title, - subheading, - imageSrc, - imageFocus, - heroContent, -}: BasicHeroMvpProps) => ( - - {imageSrc && ( - <> - - - - )} - - - {title} - - {subheading && ( - - {subheading} - - )} - {!!heroContent && ( -
- {heroContent} -
- )} -
-
-); diff --git a/components/Hero/index.ts b/components/Hero/index.ts index 80f34ee4..d49cde69 100644 --- a/components/Hero/index.ts +++ b/components/Hero/index.ts @@ -1,4 +1,4 @@ export * from './Hero'; -export * from './BasicHeroMvp'; +export * from './BasicHero'; export * from './StoryHero'; export * from './StoryHeroMvp'; diff --git a/components/Homepage/HomepageSplitHero.styles.ts b/components/Homepage/HomepageSplitHero.styles.ts index 71b37a8c..88b425c4 100644 --- a/components/Homepage/HomepageSplitHero.styles.ts +++ b/components/Homepage/HomepageSplitHero.styles.ts @@ -1,5 +1,3 @@ -import { cnb } from 'cnbuilder'; - export const root = 'relative overflow-hidden'; export const imageGridWrapper = 'relative max-h-[180rem] bg-black-true pt-170 sm:pt-[24vw] 2xl:pt-[16vw] 4xl:pt-[32rem] pb-[50vw] sm:pb-[40vw] 2xl:pb-[36vw] 4xl:pb-[64rem]'; export const mobileBg = 'sm:hidden'; diff --git a/components/Storyblok/SbBasicPage.tsx b/components/Storyblok/SbBasicPage.tsx index 9fa377d0..fc6886a3 100644 --- a/components/Storyblok/SbBasicPage.tsx +++ b/components/Storyblok/SbBasicPage.tsx @@ -1,16 +1,21 @@ import { storyblokEditable, type SbBlokData } from '@storyblok/react/rsc'; import { CreateBloks } from '@/components/CreateBloks'; -import { BasicHeroMvp } from '@/components/Hero'; +import { BasicHero } from '@/components/Hero'; import { Masthead } from '@/components/Masthead'; import { getNumBloks } from '@/utilities/getNumBloks'; import { type SbImageType } from '@/components/Storyblok/Storyblok.types'; +import { type HeroPaddingType } from '@/components/Hero/BasicHero.styles'; type SbBasicPageProps = { blok: { _uid: string; title?: string; + isDrukHeading?: boolean; + isSmallHeading?: boolean; hero?: SbBlokData[]; heroImage?: SbImageType; + paddingType?: HeroPaddingType; + superhead?: string; subheading?: string; heroContent?: SbBlokData[]; content?: SbBlokData[]; @@ -21,8 +26,12 @@ type SbBasicPageProps = { export const SbBasicPage = ({ blok: { title, + isDrukHeading, + isSmallHeading, hero, heroImage: { filename, focus } = {}, + paddingType, + superhead, subheading, heroContent, content, @@ -36,21 +45,23 @@ export const SbBasicPage = ({
-
- {!!getNumBloks(hero) ? ( - - ) : ( - - )} - - -
+ {!!getNumBloks(hero) ? ( + + ) : ( + + )} + +
); diff --git a/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts index f2f9ae77..00b327be 100644 --- a/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts +++ b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts @@ -5,7 +5,7 @@ export const bgImage = 'absolute top-0 left-0 w-full h-full object-cover'; export const overlay = (hasBgGradient?: boolean) => cnb('absolute top-0 left-0 w-full h-full z-10', hasBgGradient ? 'bg-gradient-to-t' : ''); export const header = 'relative overflow-hidden cc 3xl:px-100 4xl:px-[calc((100%-1800px)/2)] z-20'; export const superhead = 'text-shadow-sm'; -export const heading = 'fluid-type-8 md:gc-splash mb-0 whitespace-pre-line'; +export const heading = 'fluid-type-7 md:gc-splash mb-0 whitespace-pre-line'; export const introWrapper = 'cc relative z-20'; export const intro = 'intro-text *:leading-display *:md:leading-cozy *:text-shadow-sm rs-mt-7 max-w-1000'; export const contentWrapper = 'relative z-20'; diff --git a/components/Storyblok/SbSection/SbSection.styles.ts b/components/Storyblok/SbSection/SbSection.styles.ts index fad20048..8157dcc5 100644 --- a/components/Storyblok/SbSection/SbSection.styles.ts +++ b/components/Storyblok/SbSection/SbSection.styles.ts @@ -24,10 +24,10 @@ export const headerContent = (hasBarColor: boolean, hasSuperhead: boolean, heade export const heading = (isSerifHeader: boolean, isSmallHeading: boolean, headerAlign?: AlignType ) => cnb( 'mb-0', { 'text-balance mx-auto max-w-1000': headerAlign === 'center', - 'fluid-type-8 md:gc-splash': !isSerifHeader && !isSmallHeading, - 'fluid-type-8': !isSerifHeader && isSmallHeading, - 'fluid-type-6 md:fluid-type-7': isSerifHeader && !isSmallHeading, - 'fluid-type-6': isSerifHeader && isSmallHeading, + 'fluid-type-6': isSerifHeader, + 'md:fluid-type-7': isSerifHeader && !isSmallHeading, + 'fluid-type-7': !isSerifHeader, + 'md:gc-splash': !isSerifHeader && !isSmallHeading, }); export const subhead = (headerAlign?: AlignType) => cnb('relative z-10 rs-mt-3 ', { 'mr-0 ml-auto': headerAlign === 'right', From d3e6c1ff3fb789b36452e97e1aa8c26776be09ec Mon Sep 17 00:00:00 2001 From: Github Action Date: Tue, 27 Feb 2024 22:27:52 +0000 Subject: [PATCH 14/34] 1.1.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ea9a654b..d47a7ef5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ood-giving-campaign", - "version": "1.1.1", + "version": "1.1.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ood-giving-campaign", - "version": "1.1.1", + "version": "1.1.2", "dependencies": { "@heroicons/react": "^2.1.1", "@storyblok/react": "^3.0.8", diff --git a/package.json b/package.json index f7e31f10..4e9fdba9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ood-giving-campaign", - "version": "1.1.1", + "version": "1.1.2", "description": "Momentum", "author": "Stanford University", "keywords": [ From e9d183f2d1715401aeaa4a636145cc83f69d932b Mon Sep 17 00:00:00 2001 From: Sherakama Date: Thu, 29 Feb 2024 13:36:30 -0800 Subject: [PATCH 15/34] NoJira: Remove Editor Token (#237) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per client request: We really only share them with internal team members and leadership, but do rely on them working/being available for many days, sometimes weeks, for review – particularly by leadership. --- app/(editor)/editor/page.tsx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/app/(editor)/editor/page.tsx b/app/(editor)/editor/page.tsx index d482ac4b..caf305fa 100644 --- a/app/(editor)/editor/page.tsx +++ b/app/(editor)/editor/page.tsx @@ -89,17 +89,14 @@ async function getStoryData({ path }: PageProps['searchParams']): Promise { const validationString = searchParams['_storyblok_tk[space_id]'] + ':' + process.env.STORYBLOK_PREVIEW_EDITOR_TOKEN + ':' + searchParams['_storyblok_tk[timestamp]']; const validationToken = crypto.createHash('sha1').update(validationString).digest('hex'); - if (searchParams['_storyblok_tk[token]'] == validationToken && - Number(searchParams['_storyblok_tk[timestamp]']) > Math.floor(Date.now()/1000)-10800) { - // you're in the edit mode. + if (searchParams['_storyblok_tk[token]'] == validationToken) { + //You're in the edit mode. return true; } // Something didn't work out. From 83c21b4466bba370c8ff8a162a09b88cd55763b1 Mon Sep 17 00:00:00 2001 From: Yvonne Tang <42749717+yvonnetangsu@users.noreply.github.com> Date: Thu, 29 Feb 2024 14:34:43 -0800 Subject: [PATCH 16/34] GIVCAMP-293 | Moment poster (#236) * Moment poster * Moment poster options and styles * Conditional check for imageSrc in StoryImage * Clean up --- .../MomentPoster/MomentPoster.styles.ts | 21 +++ components/MomentPoster/MomentPoster.tsx | 168 ++++++++++++++++++ components/MomentPoster/index.ts | 1 + components/StoryImage/StoryImage.tsx | 18 +- components/Storyblok/SbMomentPoster.tsx | 76 ++++++++ components/StoryblokProvider.tsx | 2 + utilities/datasource.ts | 21 ++- 7 files changed, 298 insertions(+), 9 deletions(-) create mode 100644 components/MomentPoster/MomentPoster.styles.ts create mode 100644 components/MomentPoster/MomentPoster.tsx create mode 100644 components/MomentPoster/index.ts create mode 100644 components/Storyblok/SbMomentPoster.tsx diff --git a/components/MomentPoster/MomentPoster.styles.ts b/components/MomentPoster/MomentPoster.styles.ts new file mode 100644 index 00000000..b35b90a6 --- /dev/null +++ b/components/MomentPoster/MomentPoster.styles.ts @@ -0,0 +1,21 @@ +import { cnb } from 'cnbuilder'; + +export const root = 'relative overflow-hidden'; +export const wrapper = 'relative w-full z-10'; + +export const bgImage = 'absolute top-0 left-0 w-full h-full object-cover'; +export const overlay = (hasBgGradient?: boolean) => cnb('absolute top-0 left-0 w-full h-full z-10', hasBgGradient ? 'bg-gradient-to-t via-50%' : ''); + +export const contentWrapper = 'lg:rs-pr-9 ml-0'; + +export const heading = 'leading-[0.9] max-w-1000 mx-auto rs-mb-1'; +export const headingWrapper = 'mx-auto w-fit gap-02em'; + +export const thumbnailWrapper = 'inline-block'; +export const thumbnail = 'size-[0.75em]'; + +export const body = 'max-w-prose mx-auto rs-mt-3 *:*:text-center text-balance mb-0 *:*:text-shadow-sm'; + +export const cta = (isStackedCtas: boolean) => cnb( + 'gap-27 mx-auto w-fit *:mx-auto rs-mt-4', !isStackedCtas && 'md:flex-row', +); diff --git a/components/MomentPoster/MomentPoster.tsx b/components/MomentPoster/MomentPoster.tsx new file mode 100644 index 00000000..72985ae5 --- /dev/null +++ b/components/MomentPoster/MomentPoster.tsx @@ -0,0 +1,168 @@ +import { HTMLAttributes } from 'react'; +import { cnb } from 'cnbuilder'; +import { AnimateInView } from '../Animate'; +import { Container } from '../Container'; +import { Heading, Text } from '../Typography'; +import { FlexBox } from '../FlexBox'; +import { getProcessedImage } from '@/utilities/getProcessedImage'; +import * as styles from './MomentPoster.styles'; +import { + gradientFroms, + type GradientFromType, + gradientTos, + type GradientToType, + gradientVias, + type GradientViaType, + bgBlurs, + type BgBlurType, +} from '@/utilities/datasource'; + +type MomentPosterProps = HTMLAttributes & { + textBefore?: string; + textAfter?: string; + textNewRow?: string; + subhead?: string; + body?: React.ReactNode; + cta?: React.ReactNode; + bgImageSrc?: string; + bgImageFocus?: string; + thumbnailSrc?: string; + thumbnailFocus?: string; + gradientTop?: GradientToType; + gradientBottom?: GradientFromType; + gradientVia?: GradientViaType; + bgBlur?: BgBlurType; + isStackedCtas?: boolean; +}; + +export const MomentPoster = ({ + textBefore, + textAfter, + textNewRow, + subhead, + body, + cta, + bgImageSrc, + bgImageFocus, + thumbnailSrc, + thumbnailFocus, + gradientTop, + gradientBottom, + gradientVia, + bgBlur, + isStackedCtas, + ...props +}: MomentPosterProps) => { + // To render a dark overlay, both a top and bottom gradient color must be selected + const hasBgGradient = !!gradientTop && !!gradientBottom; + + return ( + + {!!bgImageSrc && ( + + + + + + + + )} + {/* Render the overlay if there's a background image, and if background blur or/and gradient is selected */} + {!!bgImageSrc && (bgBlur !== 'none' || hasBgGradient) && ( +
+ )} + + + + {textBefore && ( + + {textBefore} + + )} + {thumbnailSrc && + + + + } + {textAfter && ( + + {textAfter} + + )} + + {textNewRow && ( + + {textNewRow} + + )} + + {subhead && ( + + + {subhead} + + + )} + {body && ( + + + {body} + + + )} + {cta && ( + + + {cta} + + + )} + + + ); +}; diff --git a/components/MomentPoster/index.ts b/components/MomentPoster/index.ts new file mode 100644 index 00000000..3f4701b2 --- /dev/null +++ b/components/MomentPoster/index.ts @@ -0,0 +1 @@ +export * from './MomentPoster'; diff --git a/components/StoryImage/StoryImage.tsx b/components/StoryImage/StoryImage.tsx index 5497421d..53f2da98 100644 --- a/components/StoryImage/StoryImage.tsx +++ b/components/StoryImage/StoryImage.tsx @@ -67,14 +67,16 @@ export const StoryImage = ({
- {alt + {!!imageSrc && ( + {alt + )}
{caption && ( diff --git a/components/Storyblok/SbMomentPoster.tsx b/components/Storyblok/SbMomentPoster.tsx new file mode 100644 index 00000000..6c020f40 --- /dev/null +++ b/components/Storyblok/SbMomentPoster.tsx @@ -0,0 +1,76 @@ +import { storyblokEditable, type SbBlokData } from '@storyblok/react/rsc'; +import { type StoryblokRichtext } from 'storyblok-rich-text-react-renderer-ts'; +import { MomentPoster } from '../MomentPoster'; +import { CreateBloks } from '../CreateBloks'; +import { RichText } from '../RichText'; +import { type SbImageType } from './Storyblok.types'; +import { hasRichText } from '@/utilities/hasRichText'; +import { getNumBloks } from '@/utilities/getNumBloks'; +import { + type GradientFromType, + type GradientToType, + type GradientViaType, + BgBlurType, +} from '@/utilities/datasource'; + +type SbMomentPosterProps = { + blok: { + _uid: string; + textBefore?: string; + textAfter?: string; + textNewRow?: string; + subhead?: string; + body: StoryblokRichtext; + cta?: SbBlokData[]; + bgImage?: SbImageType; + thumbnail?: SbImageType; + gradientTop?: GradientToType; + gradientBottom?: GradientFromType; + gradientVia?: GradientViaType; + bgBlur?: BgBlurType; + isStackedCtas?: boolean; + }; +}; + +export const SbMomentPoster = ({ + blok: { + textBefore, + textAfter, + textNewRow, + subhead, + body, + cta, + bgImage: { filename, focus } = {}, + thumbnail: { filename: thumbnailFilename, focus: thumbnailFocus } = {}, + gradientTop, + gradientBottom, + gradientVia, + bgBlur, + isStackedCtas, + }, + blok, +}: SbMomentPosterProps) => { + const Cta = !!getNumBloks(cta) ? : undefined; + const Body = hasRichText(body) ? : undefined; + + return ( + + ); +}; diff --git a/components/StoryblokProvider.tsx b/components/StoryblokProvider.tsx index 1483dc4c..cd7cf792 100644 --- a/components/StoryblokProvider.tsx +++ b/components/StoryblokProvider.tsx @@ -13,6 +13,7 @@ import { SbFeatureMasonry } from '@/components/Storyblok/SbFeatureMasonry'; import { SbHomepageMvp } from '@/components/Storyblok/SbHomepageMvp'; import { SbHomepageThemeSection } from '@/components/Storyblok/SbHomepageThemeSection'; import { SbInitiativeCard } from '@/components/Storyblok/SbInitiativeCard'; +import { SbMomentPoster } from './Storyblok/SbMomentPoster'; import { SbQuote } from '@/components/Storyblok/SbQuote'; import { SbScrollytelling } from '@/components/Storyblok/SbScrollytelling'; import { SbSection } from '@/components/Storyblok/SbSection'; @@ -42,6 +43,7 @@ export const components = { sbHomepageMvp: SbHomepageMvp, sbHomepageThemeSection: SbHomepageThemeSection, sbInitiativeCard: SbInitiativeCard, + sbMomentPoster: SbMomentPoster, sbQuote: SbQuote, sbScrollytelling: SbScrollytelling, sbSection: SbSection, diff --git a/utilities/datasource.ts b/utilities/datasource.ts index 98f70273..9e8adada 100644 --- a/utilities/datasource.ts +++ b/utilities/datasource.ts @@ -76,10 +76,14 @@ export const gradientTos = { 'black-50': 'to-black-true/50', 'black-60': 'to-black-true/60', 'black-70': 'to-black-true/70', + 'black-80': 'to-black-true/80', + 'black-90': 'to-black-true/90', + 'gc-black': 'to-gc-black', }; export type GradientToType = keyof typeof gradientTos; export const gradientFroms = { + transparent: 'from-transparent', 'black-10': 'from-black-true/10', 'black-20': 'from-black-true/20', 'black-30': 'from-black-true/30', @@ -93,6 +97,21 @@ export const gradientFroms = { }; export type GradientFromType = keyof typeof gradientFroms; +export const gradientVias = { + transparent: 'via-transparent', + 'black-10': 'via-black-true/10', + 'black-20': 'via-black-true/20', + 'black-30': 'via-black-true/30', + 'black-40': 'via-black-true/40', + 'black-50': 'via-black-true/50', + 'black-60': 'via-black-true/60', + 'black-70': 'via-black-true/70', + 'black-80': 'via-black-true/80', + 'black-90': 'via-black-true/90', + 'gc-black': 'via-gc-black', +}; +export type GradientViaType = keyof typeof gradientVias; + export const imageAspectRatios = { '1x1': 'aspect-w-1 aspect-h-1', '1x2': 'aspect-w-1 aspect-h-2', @@ -124,7 +143,7 @@ export const storyHeroAspectRatiosDesktop = { '2x1': 'lg:aspect-w-2 lg:aspect-h-1', '5x8': 'lg:aspect-w-5 lg:aspect-h-8', '16x9': 'lg:aspect-w-16 lg:aspect-h-9', - 'free': '', + free: '', }; export const mediaAspectRatios = { From 0b78eee5a445f78742256a1f1f4d85d4f3b69d8d Mon Sep 17 00:00:00 2001 From: Github Action Date: Fri, 1 Mar 2024 20:30:40 +0000 Subject: [PATCH 17/34] 1.2.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d47a7ef5..dd4648c4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ood-giving-campaign", - "version": "1.1.2", + "version": "1.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ood-giving-campaign", - "version": "1.1.2", + "version": "1.2.0", "dependencies": { "@heroicons/react": "^2.1.1", "@storyblok/react": "^3.0.8", diff --git a/package.json b/package.json index 4e9fdba9..36740747 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ood-giving-campaign", - "version": "1.1.2", + "version": "1.2.0", "description": "Momentum", "author": "Stanford University", "keywords": [ From fb1c80c1f81c86ddb2b52dee8a1ca4bbf19640db Mon Sep 17 00:00:00 2001 From: Yvonne Tang <42749717+yvonnetangsu@users.noreply.github.com> Date: Mon, 4 Mar 2024 14:29:06 -0800 Subject: [PATCH 18/34] GIVCAMP-304 | Add CTA region to Section and Homepage Theme/Story Section (#239) * Add CTA region to Section and HomepageThemeStorySection * clean up --- .../SbHomepageThemeSection.styles.ts | 1 + .../SbHomepageThemeSection/SbHomepageThemeSection.tsx | 9 +++++++++ components/Storyblok/SbSection/SbSection.styles.ts | 2 +- components/Storyblok/SbSection/SbSection.tsx | 8 ++++++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts index 00b327be..04d10758 100644 --- a/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts +++ b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts @@ -9,3 +9,4 @@ export const heading = 'fluid-type-7 md:gc-splash mb-0 whitespace-pre-line'; export const introWrapper = 'cc relative z-20'; export const intro = 'intro-text *:leading-display *:md:leading-cozy *:text-shadow-sm rs-mt-7 max-w-1000'; export const contentWrapper = 'relative z-20'; +export const cta = 'relative cc md:flex-row *:mx-auto rs-mt-6 gap-20 lg:gap-27 w-fit'; diff --git a/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.tsx b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.tsx index 0823cde2..2b61d9d3 100644 --- a/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.tsx +++ b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.tsx @@ -3,6 +3,7 @@ import { AnimateInView } from '@/components/Animate'; import { storyblokEditable, type SbBlokData } from '@storyblok/react/rsc'; import { type StoryblokRichtext } from 'storyblok-rich-text-react-renderer-ts'; import { CreateBloks } from '@/components/CreateBloks'; +import { FlexBox } from '@/components/FlexBox'; import { Heading, SrOnlyText, Text } from '@/components/Typography'; import { Container } from '@/components/Container'; import { RichText } from '@/components/RichText'; @@ -13,6 +14,7 @@ import * as styles from './SbHomepageThemeSection.styles'; import { bgBlurs, type BgBlurType, gradientFroms, type GradientFromType, gradientTos, type GradientToType, } from '@/utilities/datasource'; +import { getNumBloks } from '@/utilities/getNumBloks'; type SbHomepageThemeSectionProps = { blok: { @@ -21,6 +23,7 @@ type SbHomepageThemeSectionProps = { heading?: string; intro?: StoryblokRichtext; content?: SbBlokData[]; + cta?: SbBlokData[]; bgImage?: SbImageType; bgBlur?: BgBlurType; gradientTop?: GradientToType; @@ -34,6 +37,7 @@ export const SbHomepageThemeSection = ({ heading, intro, content, + cta, bgImage: { filename, focus } = {}, bgBlur, gradientTop, @@ -137,6 +141,11 @@ export const SbHomepageThemeSection = ({ + {!!getNumBloks(cta) && ( + + + + )} ); }; diff --git a/components/Storyblok/SbSection/SbSection.styles.ts b/components/Storyblok/SbSection/SbSection.styles.ts index 8157dcc5..3f801cac 100644 --- a/components/Storyblok/SbSection/SbSection.styles.ts +++ b/components/Storyblok/SbSection/SbSection.styles.ts @@ -1,4 +1,3 @@ -import { header } from '@/components/Scrollytelling'; import { cnb } from 'cnbuilder'; export type AlignType = 'left' | 'center' | 'right'; @@ -35,4 +34,5 @@ export const subhead = (headerAlign?: AlignType) => cnb('relative z-10 rs-mt-3 ' 'max-w-prose': headerAlign !== 'center', }); export const contentWrapper = 'relative z-10'; +export const cta = 'cc md:flex-row *:mx-auto rs-mt-3 gap-20 lg:gap-27 w-fit'; export const caption = 'caption *:leading-display mt-08em max-w-prose-wide'; diff --git a/components/Storyblok/SbSection/SbSection.tsx b/components/Storyblok/SbSection/SbSection.tsx index a5e54e6e..f08644ae 100644 --- a/components/Storyblok/SbSection/SbSection.tsx +++ b/components/Storyblok/SbSection/SbSection.tsx @@ -23,6 +23,7 @@ import { paletteAccentColors, type PaletteAccentHexColorType } from '@/utilities import { type SbImageType, type SbColorStopProps } from '../Storyblok.types'; import { getProcessedImage } from '@/utilities/getProcessedImage'; import { hasRichText } from '@/utilities/hasRichText'; +import { getNumBloks } from '@/utilities/getNumBloks'; import * as styles from './SbSection.styles'; type SbSectionProps = { @@ -36,6 +37,7 @@ type SbSectionProps = { headingLevel?: HeadingType; isSerifHeader?: boolean; subheading?: string; + cta?: SbBlokData[]; caption?: StoryblokRichtext; captionColumnWidth?: '12' | '10' | '8' | '6' | '4'; barColor?: { @@ -61,6 +63,7 @@ export const SbSection = ({ isSerifHeader, headingLevel, subheading, + cta, caption, captionColumnWidth, barColor: { value: barColorValue } = {}, @@ -182,6 +185,11 @@ export const SbSection = ({ + {!!getNumBloks(cta) && ( + + + + )} {hasRichText(caption) && ( From 879b34191ada47acd46f3941dc539ca8a337e400 Mon Sep 17 00:00:00 2001 From: Yvonne Tang <42749717+yvonnetangsu@users.noreply.github.com> Date: Mon, 4 Mar 2024 16:31:31 -0800 Subject: [PATCH 19/34] Icon animation (#240) --- components/Cta/Cta.styles.ts | 4 ++++ components/HeroIcon/HeroIcon.styles.tsx | 11 ++++++----- components/Storyblok/SbCta.tsx | 12 ++++++++++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/components/Cta/Cta.styles.ts b/components/Cta/Cta.styles.ts index 700ee1a0..f2bbb8ab 100644 --- a/components/Cta/Cta.styles.ts +++ b/components/Cta/Cta.styles.ts @@ -131,6 +131,7 @@ export const ctaIconMap: CtaIconMapType = { }; export const iconAnimation = { + none: '', 'top-right': 'group-hocus:translate-x-01em group-hocus:-translate-y-01em', down: 'group-hocus:translate-y-02em', up: 'group-hocus:-translate-y-02em', @@ -152,6 +153,9 @@ export const iconLeftMarginDefault = 'ml-03em'; export const iconLeftMargin: CtaIconLeftMarginType = { 'arrow-right': 'ml-04em', back: 'ml-04em', + email: 'ml-05em', + external: 'ml-04em', + link: 'ml-05em', 'triangle-right': 'ml-04em', 'triangle-down': 'ml-04em', 'triangle-up': 'ml-04em', diff --git a/components/HeroIcon/HeroIcon.styles.tsx b/components/HeroIcon/HeroIcon.styles.tsx index 6a186bdd..69ee5a2b 100644 --- a/components/HeroIcon/HeroIcon.styles.tsx +++ b/components/HeroIcon/HeroIcon.styles.tsx @@ -73,13 +73,14 @@ export const iconBaseStyleDefault = 'w-1em'; export const iconBaseStyle: IconBaseStyleType = { 'arrow-left': 'w-09em -mt-01em', 'arrow-right': 'w-09em -mt-01em', - 'triangle-right': 'w-09em scale-x-[0.9] mt-01em', - 'triangle-down': 'w-09em scale-x-[0.9] rotate-90 mt-01em', - 'triangle-up': 'w-09em scale-x-[0.9] -rotate-90 mt-02em', - email: 'w-[1.2em]', + 'triangle-right': 'w-09em scale-x-90 mt-01em', + 'triangle-down': 'w-09em scale-x-90 rotate-90 mt-01em', + 'triangle-up': 'w-09em scale-x-90 -rotate-90 mt-02em', + download: 'w-09em', + email: 'w-1em', external: 'w-08em', left: 'w-08em', - link: 'w-1em -mt-01em', + link: 'w-09em -mt-01em', more: 'w-08em', plus: 'w-08em', right: 'w-08em', diff --git a/components/Storyblok/SbCta.tsx b/components/Storyblok/SbCta.tsx index 2ec75d2e..967e4920 100644 --- a/components/Storyblok/SbCta.tsx +++ b/components/Storyblok/SbCta.tsx @@ -1,8 +1,13 @@ import { storyblokEditable } from '@storyblok/react/rsc'; -import { CtaLink, type CtaColorType, type CtaVariantType } from '../Cta'; +import { + CtaLink, + type CtaColorType, + type CtaVariantType, + type CtaCurveType, + type IconAnimationType, +} from '../Cta'; import { type IconType } from '../HeroIcon'; import { type SbLinkType } from './Storyblok.types'; -import { type CtaCurveType } from '../Cta'; type SbCtaType = { blok: { @@ -14,6 +19,7 @@ type SbCtaType = { curve?: CtaCurveType; isLarge?: boolean; icon?: IconType; + animation?: IconAnimationType; }; }; @@ -26,6 +32,7 @@ export const SbCta = ({ curve, isLarge, icon, + animation, }, blok, }: SbCtaType) => { @@ -43,6 +50,7 @@ export const SbCta = ({ color={color} srText={srText} icon={icon} + animate={animation} > {label} From 14dc8484e448394471862e13b164681f1f2be806 Mon Sep 17 00:00:00 2001 From: Github Action Date: Tue, 5 Mar 2024 00:48:29 +0000 Subject: [PATCH 20/34] 1.2.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index dd4648c4..64ba7e78 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ood-giving-campaign", - "version": "1.2.0", + "version": "1.2.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ood-giving-campaign", - "version": "1.2.0", + "version": "1.2.1", "dependencies": { "@heroicons/react": "^2.1.1", "@storyblok/react": "^3.0.8", diff --git a/package.json b/package.json index 36740747..250f5629 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ood-giving-campaign", - "version": "1.2.0", + "version": "1.2.1", "description": "Momentum", "author": "Stanford University", "keywords": [ From 2a4633ccb3612f65f37680e08ec8349eadbcceb6 Mon Sep 17 00:00:00 2001 From: Sherakama Date: Tue, 5 Mar 2024 13:39:51 -0800 Subject: [PATCH 21/34] HSTS set max-age to 31536000 (#242) --- netlify.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netlify.toml b/netlify.toml index 07979dba..e5c33163 100644 --- a/netlify.toml +++ b/netlify.toml @@ -40,7 +40,7 @@ Content-Security-Policy = "default-src https: 'unsafe-inline' 'unsafe-eval'; form-action https:; img-src https: data:; frame-ancestors https://app.storyblok.com" X-Content-Type-Options = "nosniff" Referrer-Policy = "strict-origin-when-cross-origin" - Strict-Transport-Security = "max-age=2592000" + Strict-Transport-Security = "max-age=31536000" Permissions-Policy = "vibrate=(), geolocation=(), midi=(), notifications=(), push=(), microphone=(), camera=(), magnetometer=(), gyroscope=(), speaker=()" [[redirects]] From 192620be5f25df63fc956db77e891460d54828db Mon Sep 17 00:00:00 2001 From: Yvonne Tang <42749717+yvonnetangsu@users.noreply.github.com> Date: Tue, 5 Mar 2024 17:57:33 -0800 Subject: [PATCH 22/34] GIVCAMP-294 | Basic Hero overlay options and image optimization (#243) * Basic Hero gradient and better image processing * Make conditionals better --- components/Hero/BasicHero.styles.ts | 6 +- components/Hero/BasicHero.tsx | 177 ++++++++++++------ .../MomentPoster/MomentPoster.styles.ts | 2 +- components/MomentPoster/MomentPoster.tsx | 4 +- components/Storyblok/SbBasicPage.tsx | 18 ++ .../SbHomepageThemeSection.styles.ts | 2 +- .../SbHomepageThemeSection.tsx | 4 +- 7 files changed, 145 insertions(+), 68 deletions(-) diff --git a/components/Hero/BasicHero.styles.ts b/components/Hero/BasicHero.styles.ts index acf87dae..a57b8ea3 100644 --- a/components/Hero/BasicHero.styles.ts +++ b/components/Hero/BasicHero.styles.ts @@ -9,8 +9,12 @@ export const heroPaddings = { export type HeroPaddingType = keyof typeof heroPaddings; export const root = 'relative break-words bg-black-70'; + +export const bgImage = 'absolute top-0 left-0 w-full h-full object-cover'; +export const overlay = (hasBgGradient?: boolean) => cnb('absolute top-0 left-0 w-full h-full z-10', hasBgGradient ? 'bg-gradient-to-b via-50%' : ''); + export const contentWrapper = '*:mx-auto'; -export const superhead = 'relative z-10 xl:max-w-900 mx-auto rs-mb-0'; +export const superhead = 'relative z-10 xl:max-w-900 mx-auto rs-mb-0 text-shadow-sm'; export const heading = (isDrukHeading: boolean, isSmallHeading: boolean) => cnb('relative z-10 max-w-1200 mx-auto mb-0 text-balance', { 'fluid-type-7 md:fluid-type-8': isDrukHeading && isSmallHeading, 'fluid-type-7 md:gc-splash': isDrukHeading && !isSmallHeading, diff --git a/components/Hero/BasicHero.tsx b/components/Hero/BasicHero.tsx index 41aa2b7a..24e11a79 100644 --- a/components/Hero/BasicHero.tsx +++ b/components/Hero/BasicHero.tsx @@ -3,6 +3,16 @@ import { Container } from '@/components/Container'; import { Heading, SrOnlyText, Text } from '@/components/Typography'; import { ImageOverlay } from '@/components/ImageOverlay'; import { getProcessedImage } from '@/utilities/getProcessedImage'; +import { + gradientFroms, + type GradientFromType, + gradientTos, + type GradientToType, + gradientVias, + type GradientViaType, + bgBlurs, + type BgBlurType, +} from '@/utilities/datasource'; import * as styles from './BasicHero.styles'; /** @@ -16,6 +26,10 @@ type BasicHeroProps = { subheading?: string; imageSrc?: string; imageFocus?: string; + gradientTop?: GradientToType; + gradientBottom?: GradientFromType; + gradientVia?: GradientViaType; + bgBlur?: BgBlurType; heroContent?: React.ReactNode; paddingType?: styles.HeroPaddingType; }; @@ -28,72 +42,113 @@ export const BasicHero = ({ subheading, imageSrc, imageFocus, + gradientTop, + gradientBottom, + gradientVia, + bgBlur, heroContent, paddingType, -}: BasicHeroProps) => ( - - {imageSrc && ( - <> - - { + // To render a dark overlay, both a top and bottom gradient color must be selected + const hasBgGradient = !!gradientTop && !!gradientBottom; + const hasBgBlur = !!bgBlur && bgBlur !== 'none'; + + return ( + + {!!imageSrc && ( + + + + + + + + )} + {!!imageSrc && (hasBgBlur || hasBgGradient) && ( +
- - )} - - {superhead && ( - - {superhead} - )} - - {superhead && {`${superhead}: `}}{title} - - {subheading && ( - + {superhead && ( + + {superhead} + + )} + - {subheading} - - )} - {!!heroContent && ( -
- {heroContent} -
- )} + {superhead && {`${superhead}: `}}{title} + + {subheading && ( + + {subheading} + + )} + {!!heroContent && ( +
+ {heroContent} +
+ )} +
- -); + ); +}; diff --git a/components/MomentPoster/MomentPoster.styles.ts b/components/MomentPoster/MomentPoster.styles.ts index b35b90a6..74dfb3fa 100644 --- a/components/MomentPoster/MomentPoster.styles.ts +++ b/components/MomentPoster/MomentPoster.styles.ts @@ -4,7 +4,7 @@ export const root = 'relative overflow-hidden'; export const wrapper = 'relative w-full z-10'; export const bgImage = 'absolute top-0 left-0 w-full h-full object-cover'; -export const overlay = (hasBgGradient?: boolean) => cnb('absolute top-0 left-0 w-full h-full z-10', hasBgGradient ? 'bg-gradient-to-t via-50%' : ''); +export const overlay = (hasBgGradient?: boolean) => cnb('absolute top-0 left-0 w-full h-full z-10', hasBgGradient ? 'bg-gradient-to-b via-50%' : ''); export const contentWrapper = 'lg:rs-pr-9 ml-0'; diff --git a/components/MomentPoster/MomentPoster.tsx b/components/MomentPoster/MomentPoster.tsx index 72985ae5..329335ca 100644 --- a/components/MomentPoster/MomentPoster.tsx +++ b/components/MomentPoster/MomentPoster.tsx @@ -100,9 +100,9 @@ export const MomentPoster = ({ className={cnb( styles.overlay(hasBgGradient), bgBlurs[bgBlur], - gradientFroms[gradientBottom], + gradientFroms[gradientTop], gradientVias[gradientVia], - gradientTos[gradientTop], + gradientTos[gradientBottom], )} /> )} diff --git a/components/Storyblok/SbBasicPage.tsx b/components/Storyblok/SbBasicPage.tsx index fc6886a3..a5ddc63b 100644 --- a/components/Storyblok/SbBasicPage.tsx +++ b/components/Storyblok/SbBasicPage.tsx @@ -5,6 +5,12 @@ import { Masthead } from '@/components/Masthead'; import { getNumBloks } from '@/utilities/getNumBloks'; import { type SbImageType } from '@/components/Storyblok/Storyblok.types'; import { type HeroPaddingType } from '@/components/Hero/BasicHero.styles'; +import { + type GradientFromType, + type GradientToType, + type GradientViaType, + BgBlurType, +} from '@/utilities/datasource'; type SbBasicPageProps = { blok: { @@ -14,6 +20,10 @@ type SbBasicPageProps = { isSmallHeading?: boolean; hero?: SbBlokData[]; heroImage?: SbImageType; + gradientTop?: GradientToType; + gradientBottom?: GradientFromType; + gradientVia?: GradientViaType; + bgBlur?: BgBlurType; paddingType?: HeroPaddingType; superhead?: string; subheading?: string; @@ -30,6 +40,10 @@ export const SbBasicPage = ({ isSmallHeading, hero, heroImage: { filename, focus } = {}, + gradientTop, + gradientBottom, + gradientVia, + bgBlur, paddingType, superhead, subheading, @@ -56,6 +70,10 @@ export const SbBasicPage = ({ subheading={subheading} imageSrc={filename} imageFocus={focus} + gradientTop={gradientTop} + gradientBottom={gradientBottom} + gradientVia={gradientVia} + bgBlur={bgBlur} heroContent={HeroContent} paddingType={paddingType} /> diff --git a/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts index 04d10758..d41e6417 100644 --- a/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts +++ b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts @@ -2,7 +2,7 @@ import { cnb } from 'cnbuilder'; export const root = 'relative overflow-hidden'; export const bgImage = 'absolute top-0 left-0 w-full h-full object-cover'; -export const overlay = (hasBgGradient?: boolean) => cnb('absolute top-0 left-0 w-full h-full z-10', hasBgGradient ? 'bg-gradient-to-t' : ''); +export const overlay = (hasBgGradient?: boolean) => cnb('absolute top-0 left-0 w-full h-full z-10', hasBgGradient ? 'bg-gradient-to-b' : ''); export const header = 'relative overflow-hidden cc 3xl:px-100 4xl:px-[calc((100%-1800px)/2)] z-20'; export const superhead = 'text-shadow-sm'; export const heading = 'fluid-type-7 md:gc-splash mb-0 whitespace-pre-line'; diff --git a/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.tsx b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.tsx index 2b61d9d3..10959e16 100644 --- a/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.tsx +++ b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.tsx @@ -97,8 +97,8 @@ export const SbHomepageThemeSection = ({ className={cnb( styles.overlay(hasBgGradient), bgBlurs[bgBlur], - gradientFroms[gradientBottom], - gradientTos[gradientTop], + gradientFroms[gradientTop], + gradientTos[gradientBottom], )} /> )} From 239b53c9407033cc44cef5c583245727342fc764 Mon Sep 17 00:00:00 2001 From: Github Action Date: Wed, 6 Mar 2024 02:12:29 +0000 Subject: [PATCH 23/34] 1.2.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 64ba7e78..b0dfa27f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ood-giving-campaign", - "version": "1.2.1", + "version": "1.2.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ood-giving-campaign", - "version": "1.2.1", + "version": "1.2.2", "dependencies": { "@heroicons/react": "^2.1.1", "@storyblok/react": "^3.0.8", diff --git a/package.json b/package.json index 250f5629..b007d4c8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ood-giving-campaign", - "version": "1.2.1", + "version": "1.2.2", "description": "Momentum", "author": "Stanford University", "keywords": [ From f995104f7ba76bcf8e7be5b4286388c3a4c5209d Mon Sep 17 00:00:00 2001 From: Yvonne Tang <42749717+yvonnetangsu@users.noreply.github.com> Date: Tue, 12 Mar 2024 15:09:45 -0700 Subject: [PATCH 24/34] GIVCAMP-88 | data card (#245) * DataCard setup; replace "Giving Campaign" with "Momentum"; add new line height in TW theme * Add druk leading option * DataCard styles WIP * Number counter and full height within grid * Modify demo content because props changed * counter function * clean up * Accessible headings; remove isSmallHeading prop --- README.md | 4 +- components/DataCard/DataCard.styles.ts | 16 ++++ components/DataCard/DataCard.tsx | 93 +++++++++++++++++++ components/DataCard/index.ts | 1 + components/Homepage/IdealFellow.tsx | 4 +- .../MomentPoster/MomentPoster.styles.ts | 2 +- components/MomentPoster/MomentPoster.tsx | 2 +- components/NumberCounter.tsx | 12 +-- components/Storyblok/SbDataCard.tsx | 69 ++++++++++++++ components/StoryblokProvider.tsx | 2 + components/Temporary/DemoContent.tsx | 2 +- components/Typography/typography.styles.ts | 7 +- tailwind.config.ts | 3 +- tailwind/plugins/base/gc-base.js | 4 +- tailwind/plugins/components/gc-typography.js | 2 +- tailwind/plugins/theme/gc-colors.js | 2 +- tailwind/plugins/theme/gc-fontFamily.js | 2 +- tailwind/plugins/theme/gc-lineHeight.js | 9 ++ utilities/splitNumberString.ts | 23 +++++ 19 files changed, 235 insertions(+), 24 deletions(-) create mode 100644 components/DataCard/DataCard.styles.ts create mode 100644 components/DataCard/DataCard.tsx create mode 100644 components/DataCard/index.ts create mode 100644 components/Storyblok/SbDataCard.tsx create mode 100644 tailwind/plugins/theme/gc-lineHeight.js create mode 100644 utilities/splitNumberString.ts diff --git a/README.md b/README.md index dfefa8ff..e43af93f 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# [Giving Campaign (Stanford On Purpose)](https://github.com/SU-SWS/ood-giving-campaign) +# [Stanford Momentum](https://github.com/SU-SWS/ood-giving-campaign) [![Netlify Status](https://api.netlify.com/api/v1/badges/738e5599-7329-41a1-8429-82f8540636d9/deploy-status?branch=dev)](https://app.netlify.com/sites/giving-campaign/deploys) Description --- -Netlify hosted, Next.js built, Storyblok headless CMS site for the Stanford On Purpose website. +Netlify hosted, Next.js built, Storyblok headless CMS site for the Stanford Momentum website. Environment variable set up and installation --- diff --git a/components/DataCard/DataCard.styles.ts b/components/DataCard/DataCard.styles.ts new file mode 100644 index 00000000..168d3002 --- /dev/null +++ b/components/DataCard/DataCard.styles.ts @@ -0,0 +1,16 @@ +import { cnb } from 'cnbuilder'; + +export const animateWrapper = 'h-full'; +// Use border-black-50/50 which works well on both light and dark backgrounds +export const root = 'relative overflow-hidden size-full break-words border-l-2 border-black-50/50'; + +export const flex = 'h-full'; +export const content = ( + hasBarColor?: boolean, +) => cnb('rs-pl-2', { + 'border-l-[1.4rem] md:border-l-[2rem]': hasBarColor, +}); + +export const heading = 'rs-mb-3 ml-22 whitespace-pre-line mt-auto'; +export const body = '*:*:leading-snug'; +export const cta = 'rs-mt-2'; diff --git a/components/DataCard/DataCard.tsx b/components/DataCard/DataCard.tsx new file mode 100644 index 00000000..2cd842ad --- /dev/null +++ b/components/DataCard/DataCard.tsx @@ -0,0 +1,93 @@ +import { cnb } from 'cnbuilder'; +import { AnimateInView, type AnimationType } from '@/components/Animate'; +import { NumberCounter } from '@/components/NumberCounter'; +import { Container } from '@/components/Container'; +import { FlexBox } from '@/components/FlexBox'; +import { Heading, type HeadingType } from '../Typography'; +import { accentBorderColors, type AccentBorderColorType, type PaddingType } from '@/utilities/datasource'; +import { splitNumberString } from '@/utilities/splitNumberString'; +import * as styles from './DataCard.styles'; + +export type DataCardProps = React.HTMLAttributes & { + heading?: string; + headingLevel?: HeadingType; + isDarkTheme?: boolean; + barColor?: AccentBorderColorType; + body?: React.ReactNode; + paddingTop?: PaddingType; + cta?: React.ReactNode; + isCounter?: boolean; + // In number of seconds + counterDuration?: number; + animation?: AnimationType; + delay?: number; +}; + +export const DataCard = ({ + heading, + headingLevel = 'h3', + barColor, + body, + cta, + paddingTop, + isDarkTheme, + isCounter, + counterDuration, + animation = 'slideUp', + delay, + children, + className, + ...props +}: DataCardProps) => { + const headingProcessed = isCounter ? splitNumberString(heading) : undefined; + + return ( + + + + {/* If number counter is enabled, aria-hidden the animated heading and add a SR only heading */} + {isCounter && heading && ( + {heading} + )} + {heading && ( + + {isCounter ? ( + <> + {headingProcessed?.beforeNumber} + + {headingProcessed?.afterNumber} + + ) : ( + heading + )} + + )} +
+
+ {body} +
+ {!!cta && ( +
+ {cta} +
+ )} +
+
+
+
+ ); +}; diff --git a/components/DataCard/index.ts b/components/DataCard/index.ts new file mode 100644 index 00000000..e8082810 --- /dev/null +++ b/components/DataCard/index.ts @@ -0,0 +1 @@ +export * from './DataCard'; diff --git a/components/Homepage/IdealFellow.tsx b/components/Homepage/IdealFellow.tsx index 66800b7c..2721d32e 100644 --- a/components/Homepage/IdealFellow.tsx +++ b/components/Homepage/IdealFellow.tsx @@ -23,8 +23,8 @@ export const IdealFellow = () => {
Shape - what’s - next + what’s + next
Preparing citizens diff --git a/components/MomentPoster/MomentPoster.styles.ts b/components/MomentPoster/MomentPoster.styles.ts index 74dfb3fa..6426f129 100644 --- a/components/MomentPoster/MomentPoster.styles.ts +++ b/components/MomentPoster/MomentPoster.styles.ts @@ -8,7 +8,7 @@ export const overlay = (hasBgGradient?: boolean) => cnb('absolute top-0 left-0 w export const contentWrapper = 'lg:rs-pr-9 ml-0'; -export const heading = 'leading-[0.9] max-w-1000 mx-auto rs-mb-1'; +export const heading = 'max-w-1000 mx-auto rs-mb-1'; export const headingWrapper = 'mx-auto w-fit gap-02em'; export const thumbnailWrapper = 'inline-block'; diff --git a/components/MomentPoster/MomentPoster.tsx b/components/MomentPoster/MomentPoster.tsx index 329335ca..c21f7c80 100644 --- a/components/MomentPoster/MomentPoster.tsx +++ b/components/MomentPoster/MomentPoster.tsx @@ -107,7 +107,7 @@ export const MomentPoster = ({ /> )} - + {textBefore && ( diff --git a/components/NumberCounter.tsx b/components/NumberCounter.tsx index 21d215c5..0eb4a9ef 100644 --- a/components/NumberCounter.tsx +++ b/components/NumberCounter.tsx @@ -1,22 +1,18 @@ 'use client'; import React, { useState, useEffect, useRef } from 'react'; import { m, useInView } from 'framer-motion'; -import { Text } from './Typography'; -/** - * TODO: This is a POC. Will add types and props if client decides we need this. - */ type NumberCounterProps = { number: number; duration?: number; - afterText?: string; }; -export const NumberCounter = ({ number, duration = 2500, afterText = '' }: NumberCounterProps) => { +export const NumberCounter = ({ number, duration = 2.5 }: NumberCounterProps) => { const [count, setCount] = useState(1); const ref = useRef(null); const isInView = useInView(ref); - const interval = duration / number; + // Multiply duration by 1000 to convert to milliseconds + const interval = Math.floor(duration * 1000 / number); useEffect(() => { if (isInView && count < number) { @@ -28,7 +24,7 @@ export const NumberCounter = ({ number, duration = 2500, afterText = '' }: Numbe return ( 0 ? 1 : 0 }} ref={ref}> - {count}{afterText} + {count} ); }; diff --git a/components/Storyblok/SbDataCard.tsx b/components/Storyblok/SbDataCard.tsx new file mode 100644 index 00000000..fd02611f --- /dev/null +++ b/components/Storyblok/SbDataCard.tsx @@ -0,0 +1,69 @@ +import { storyblokEditable, type SbBlokData } from '@storyblok/react/rsc'; +import { type StoryblokRichtext } from 'storyblok-rich-text-react-renderer-ts'; +import { CreateBloks } from '@/components/CreateBloks'; +import { DataCard } from '@/components/DataCard'; +import { RichText } from '@/components/RichText'; +import { type AnimationType } from '@/components/Animate'; +import { type HeadingType } from '@/components/Typography'; +import { paletteAccentColors, type PaletteAccentHexColorType } from '@/utilities/colorPalettePlugin'; +import { type PaddingType } from '@/utilities/datasource'; +import { getNumBloks } from '@/utilities/getNumBloks'; +import { hasRichText } from '@/utilities/hasRichText'; + +export type SbDataCardProps = { + blok: { + _uid: string; + heading?: string; + headingLevel?: HeadingType; + isSmallHeading?: boolean; + superhead?: string; + body: StoryblokRichtext; + cta?: SbBlokData[]; + paddingTop?: PaddingType; + isDarkTheme?: boolean; + isCounter?: boolean; + counterDuration?: number; + barColor?: { + value?: PaletteAccentHexColorType; + } + animation?: AnimationType; + delay?: number; + }; +}; + +export const SbDataCard = ({ + blok: { + heading, + headingLevel, + body, + cta, + paddingTop, + isDarkTheme, + isCounter, + counterDuration, + barColor: { value } = {}, + animation, + delay, + }, + blok, +}: SbDataCardProps) => { + const Body = hasRichText(body) ? : undefined; + const Cta = !!getNumBloks(cta) ? : undefined; + + return ( + + ); +}; diff --git a/components/StoryblokProvider.tsx b/components/StoryblokProvider.tsx index cd7cf792..719ef54f 100644 --- a/components/StoryblokProvider.tsx +++ b/components/StoryblokProvider.tsx @@ -6,6 +6,7 @@ import { SbBlurryPoster } from '@/components/Storyblok/SbBlurryPoster'; import { SbCardWysiwyg } from '@/components/Storyblok/SbCardWysiwyg'; import { SbChangemakerCard } from '@/components/Storyblok/SbChangemakerCard'; import { SbCta } from '@/components/Storyblok/SbCta'; +import { SbDataCard } from '@/components/Storyblok/SbDataCard'; import { SbEmbedMedia } from '@/components/Storyblok/SbEmbedMedia'; import { SbGrid } from '@/components/Storyblok/SbGrid'; import { SbGridAlternating } from '@/components/Storyblok/SbGridAlternating'; @@ -36,6 +37,7 @@ export const components = { sbCardWysiwyg: SbCardWysiwyg, sbChangemakerCard: SbChangemakerCard, sbCta: SbCta, + sbDataCard: SbDataCard, sbEmbedMedia: SbEmbedMedia, sbGrid: SbGrid, sbGridAlternating: SbGridAlternating, diff --git a/components/Temporary/DemoContent.tsx b/components/Temporary/DemoContent.tsx index bb2f9aed..bff9202b 100644 --- a/components/Temporary/DemoContent.tsx +++ b/components/Temporary/DemoContent.tsx @@ -110,7 +110,7 @@ export const DemoContent = () => ( Animated counters - + diff --git a/components/Typography/typography.styles.ts b/components/Typography/typography.styles.ts index bd83d5b1..bd882d44 100644 --- a/components/Typography/typography.styles.ts +++ b/components/Typography/typography.styles.ts @@ -44,6 +44,7 @@ export const fontLeadings = { cozy: 'leading-cozy', // 1.4 normal: 'leading', // 1.5 trim: 'leading-trim', // 0.75 + druk: 'leading-druk', // 0.9 }; export const textAligns = { @@ -71,15 +72,15 @@ export const textVariants = { big: 'big-paragraph', subheading: 'subheading', /** - * Campaign typography styles - * (-gc ones are Decanter styles with Campaign modifications) + * Momentum typography styles + * (-gc ones are Decanter styles with Momentum modifications) */ caption: 'caption', card: 'gc-card', changemaker: 'gc-changemaker', intro: 'gc-intro-text', /** - * Campaign only styles + * Momentum only styles * No gc- prefix because no Decanter equivalent */ overview: 'overview', diff --git a/tailwind.config.ts b/tailwind.config.ts index 0439e888..f71636f4 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -19,10 +19,11 @@ export default { ], theme: { containers: require(`${dir}/theme/gc-containers.js`)(), - // Campaign themes extending our Decanter ones + // Momentum themes extending our Decanter ones extend: { colors: require(`${dir}/theme/gc-colors.js`)(), fontFamily: require(`${dir}/theme/gc-fontFamily.js`)(), + lineHeight: require(`${dir}/theme/gc-lineHeight.js`)(), screens: require(`${dir}/theme/gc-screens.js`)(), }, }, diff --git a/tailwind/plugins/base/gc-base.js b/tailwind/plugins/base/gc-base.js index a238ed01..7dedde13 100644 --- a/tailwind/plugins/base/gc-base.js +++ b/tailwind/plugins/base/gc-base.js @@ -1,5 +1,5 @@ /** - * Campaign custom base styles extending Decanter 7 base + * Momentum custom base styles extending Decanter 7 base */ module.exports = function () { @@ -7,7 +7,7 @@ module.exports = function () { addBase({ html: { overflowY: 'visible !important', // Need this for sticky nav to work - color: '#17171A', // Campaign black + color: '#17171A', // Momentum black }, body: { fontSize: '1.8rem', diff --git a/tailwind/plugins/components/gc-typography.js b/tailwind/plugins/components/gc-typography.js index 0a5b92a7..6ad1a516 100644 --- a/tailwind/plugins/components/gc-typography.js +++ b/tailwind/plugins/components/gc-typography.js @@ -1,5 +1,5 @@ /** - * Campaign specific typography styles + * Momentum specific typography styles */ module.exports = function () { return function ({ addComponents, theme }) { diff --git a/tailwind/plugins/theme/gc-colors.js b/tailwind/plugins/theme/gc-colors.js index 1ddcc350..976c97a7 100644 --- a/tailwind/plugins/theme/gc-colors.js +++ b/tailwind/plugins/theme/gc-colors.js @@ -1,5 +1,5 @@ /** - * Giving Campaign colors + * Momentum colors */ module.exports = function () { return { diff --git a/tailwind/plugins/theme/gc-fontFamily.js b/tailwind/plugins/theme/gc-fontFamily.js index b9ae020b..d1f54568 100644 --- a/tailwind/plugins/theme/gc-fontFamily.js +++ b/tailwind/plugins/theme/gc-fontFamily.js @@ -1,5 +1,5 @@ /** - * Giving Campaign fonts + * Momentum fonts */ module.exports = function () { return { diff --git a/tailwind/plugins/theme/gc-lineHeight.js b/tailwind/plugins/theme/gc-lineHeight.js new file mode 100644 index 00000000..f657481b --- /dev/null +++ b/tailwind/plugins/theme/gc-lineHeight.js @@ -0,0 +1,9 @@ +/** + * Momentum line heights + */ +module.exports = function () { + return { + // Extra tight line height for Druk font in some components, e.g., Data Card, Moment Poster + druk: '0.9', + }; +}; diff --git a/utilities/splitNumberString.ts b/utilities/splitNumberString.ts new file mode 100644 index 00000000..c45a1802 --- /dev/null +++ b/utilities/splitNumberString.ts @@ -0,0 +1,23 @@ +/** + * Separates a string into three parts: text before the number, the number itself, and text after the number. + * + * @param str The input string containing a number. + * @returns An object with three properties: beforeNumber, number, and afterNumber. + */ +export const splitNumberString = (str: string): { beforeNumber: string; number?: number; afterNumber: string } => { + const numberRegex = /\d+/; + const numberMatch = str.match(numberRegex); + + if (numberMatch) { + const number = parseFloat(numberMatch[0]); + const numberIndex = numberMatch.index ?? 0; + const beforeNumber = str.substring(0, numberIndex); + const afterNumber = str.substring(numberIndex + (numberMatch[0]?.length ?? 0)); + + return { + beforeNumber: beforeNumber ?? '', + number: number, + afterNumber: afterNumber ?? '', + }; + } +}; From 787545f04dfa90ca81a2233b092318b12668c457 Mon Sep 17 00:00:00 2001 From: Sherakama Date: Tue, 12 Mar 2024 16:00:47 -0700 Subject: [PATCH 25/34] GIVCAMP-289: Inline External Script Loading. (#246) * GIVCAMP-289: Inline External Script Loading. * GIVCAMP-289: Clean up script on unmount. * Update SbEmbed.tsx * fixup! Types. * Update components/Storyblok/SbEmbed.tsx Co-authored-by: Yvonne Tang <42749717+yvonnetangsu@users.noreply.github.com> * Update components/Embed/Embed.tsx Co-authored-by: Yvonne Tang <42749717+yvonnetangsu@users.noreply.github.com> --------- Co-authored-by: Yvonne Tang <42749717+yvonnetangsu@users.noreply.github.com> --- components/Embed/Embed.tsx | 89 ++++++++++++++++++++++++++++++++ components/Embed/index.ts | 2 + components/Storyblok/SbEmbed.tsx | 27 ++++++++++ components/StoryblokProvider.tsx | 2 + 4 files changed, 120 insertions(+) create mode 100644 components/Embed/Embed.tsx create mode 100644 components/Embed/index.ts create mode 100644 components/Storyblok/SbEmbed.tsx diff --git a/components/Embed/Embed.tsx b/components/Embed/Embed.tsx new file mode 100644 index 00000000..a3518e21 --- /dev/null +++ b/components/Embed/Embed.tsx @@ -0,0 +1,89 @@ +/** + * A NextJS Embed Component + * + * Credit where credit is deserved. + * @see: https://github.com/christo-pr/dangerously-set-html-content + * + * Use this widget with caution. There are no safeguards on what it can do. It + * is also not good practice to inject and manipulate the page outside of + * REACT as that can lead to irregularities and troubles. + */ +import React, { useRef, useEffect } from 'react'; +import { WidthBox, type WidthType } from '../WidthBox'; +import { type PaddingType } from '@/utilities/datasource'; + +export interface EmbedProps extends React.HTMLAttributes { + id?: string; + src?: string; + content?: string; + boundingWidth?: 'site' | 'full'; + width?: WidthType; + spacingTop?: PaddingType; + spacingBottom?: PaddingType; + className?: string; +} + +const Embed = ({ +id, src, content, boundingWidth, spacingTop, spacingBottom, className, width, ...props +}:EmbedProps) => { + + const myEmbed = useRef(null); + + useEffect(() => { + // If there is no content or src, return. + if (!content && !src) return; + const domElement = myEmbed.current; + // Clear the container. + domElement.innerHTML = ''; + + if (src.length > 1) { + // Create a script tag. + const script = document.createElement('script'); + // Set the src to the src provided. + script.src = src; + domElement.appendChild(script); + } + + if (content.length > 1) { + // Create a 'tiny' document and parse the html string. + // https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment + const miniDom = document.createRange().createContextualFragment(content); + // Force the scripts in the embed script field to load sync. + const scripts = miniDom.querySelectorAll('script'); + if (scripts.length >= 1) { + for (const item of scripts) { + if (item.src && item.src.length > 1) { + item.async = false; + item.defer = false; + } + } + } + // Append the new content. + domElement.appendChild(miniDom); + } + + return () => { + // Clean up the script tag. + domElement.innerHTML = ''; + }; + }, [content, src]); + + if (content) { + return ( + +
+ + ); + } + + return (

You must provide either an src or content to the embed

); +}; + +export default Embed; diff --git a/components/Embed/index.ts b/components/Embed/index.ts new file mode 100644 index 00000000..0effca01 --- /dev/null +++ b/components/Embed/index.ts @@ -0,0 +1,2 @@ +import Embed from './Embed'; +export { Embed }; diff --git a/components/Storyblok/SbEmbed.tsx b/components/Storyblok/SbEmbed.tsx new file mode 100644 index 00000000..9c135e47 --- /dev/null +++ b/components/Storyblok/SbEmbed.tsx @@ -0,0 +1,27 @@ +import { storyblokEditable} from '@storyblok/react/rsc'; +import { Embed } from '@/components/Embed'; +import { type WidthType } from '../WidthBox'; +import { type PaddingType } from '@/utilities/datasource'; + +type SbEmbedProps = { + blok: { + _uid: string; + src?: string; + content?: string; + boundingWidth?: 'site' | 'full'; + width?: WidthType; + spacingTop?: PaddingType; + spacingBottom?: PaddingType; + }; +}; + +export const SbEmbed = ({ blok, blok: { _uid } }:SbEmbedProps) => { + + return ( + + ); +}; diff --git a/components/StoryblokProvider.tsx b/components/StoryblokProvider.tsx index 719ef54f..c0f9aaa5 100644 --- a/components/StoryblokProvider.tsx +++ b/components/StoryblokProvider.tsx @@ -7,6 +7,7 @@ import { SbCardWysiwyg } from '@/components/Storyblok/SbCardWysiwyg'; import { SbChangemakerCard } from '@/components/Storyblok/SbChangemakerCard'; import { SbCta } from '@/components/Storyblok/SbCta'; import { SbDataCard } from '@/components/Storyblok/SbDataCard'; +import { SbEmbed } from '@/components/Storyblok/SbEmbed'; import { SbEmbedMedia } from '@/components/Storyblok/SbEmbedMedia'; import { SbGrid } from '@/components/Storyblok/SbGrid'; import { SbGridAlternating } from '@/components/Storyblok/SbGridAlternating'; @@ -38,6 +39,7 @@ export const components = { sbChangemakerCard: SbChangemakerCard, sbCta: SbCta, sbDataCard: SbDataCard, + sbEmbedScript: SbEmbed, sbEmbedMedia: SbEmbedMedia, sbGrid: SbGrid, sbGridAlternating: SbGridAlternating, From 7c7086ed159d42af0a784cababf0364a7f49142c Mon Sep 17 00:00:00 2001 From: Github Action Date: Wed, 13 Mar 2024 17:29:57 +0000 Subject: [PATCH 26/34] 1.3.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index b0dfa27f..0769cc1e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ood-giving-campaign", - "version": "1.2.2", + "version": "1.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ood-giving-campaign", - "version": "1.2.2", + "version": "1.3.0", "dependencies": { "@heroicons/react": "^2.1.1", "@storyblok/react": "^3.0.8", diff --git a/package.json b/package.json index b007d4c8..2f616779 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ood-giving-campaign", - "version": "1.2.2", + "version": "1.3.0", "description": "Momentum", "author": "Stanford University", "keywords": [ From 7a4dfb137efe38bade59f29fe1149b15f3bea563 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Mar 2024 10:31:06 -0700 Subject: [PATCH 27/34] Bump follow-redirects from 1.15.4 to 1.15.6 (#249) Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0769cc1e..3d324aba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2390,9 +2390,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", - "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "funding": [ { "type": "individual", From 395be3782eb52b09f16e32a194211044b5cf734f Mon Sep 17 00:00:00 2001 From: Yvonne Tang <42749717+yvonnetangsu@users.noreply.github.com> Date: Mon, 18 Mar 2024 15:48:53 -0700 Subject: [PATCH 28/34] GIVCAMP-297 GIVCAMP-312 | Section background options + add light overlay options (#248) * New section options * Replace all w-full h-full with size-full * Add middle overlay option for Homepage Theme Story Section also * Add white overlay options; make moment poster image loading lazy * No textshadows on light theme --- .../BlurryPoster/BlurryPoster.styles.tsx | 4 +- components/Bookshelf/Book.tsx | 2 +- components/Bookshelf/BookAlt.tsx | 2 +- components/BracketCard/BracketCard.styles.ts | 2 +- .../ChangemakerCard/ChangemakerCard.styles.ts | 10 +-- components/FeaturedStories/FeatureMasonry.tsx | 6 +- components/Hero/BasicHero.styles.ts | 4 +- components/Hero/StoryHero.styles.ts | 4 +- components/Hero/StoryHeroMvp.styles.ts | 4 +- components/Homepage/BelowBlockBanner.tsx | 2 +- components/Homepage/Changemaker.tsx | 2 +- .../Homepage/HomepageSplitHero.styles.ts | 8 +-- components/ImageOverlay.tsx | 4 +- .../InitiativeCard/InitiativeCard.styles.ts | 4 +- .../LocalFooter/LocalFooterMvp.styles.tsx | 2 +- .../MomentPoster/MomentPoster.styles.ts | 6 +- components/MomentPoster/MomentPoster.tsx | 8 ++- .../Scrollytelling/Scrollytelling.styles.ts | 4 +- .../Scrollytelling/ScrollytellingDemo.tsx | 8 +-- components/StoryCard/StoryCard.styles.tsx | 2 +- components/StoryImage/StoryImage.styles.ts | 2 +- components/StoryPoC/BrochureChapter2.tsx | 8 +-- components/StoryPoC/BrochureStory.tsx | 4 +- components/StoryPoC/ProgressStory.tsx | 10 +-- components/StoryPoC/VideoScrollStory.tsx | 6 +- .../SbHomepageThemeSection.styles.ts | 8 +-- .../SbHomepageThemeSection.tsx | 26 +++++-- components/Storyblok/SbMomentPoster.tsx | 5 +- .../Storyblok/SbSection/SbSection.styles.ts | 3 + components/Storyblok/SbSection/SbSection.tsx | 72 +++++++++++++++++-- components/Temporary/DemoContent.tsx | 4 +- components/TexturedBar/TexturedBar.tsx | 2 +- components/ThemeCard/ThemeCard.styles.tsx | 2 +- components/Typography/typography.styles.ts | 1 + .../VerticalPoster/VerticalPoster.styles.ts | 2 +- utilities/datasource.ts | 30 ++++++++ 36 files changed, 194 insertions(+), 79 deletions(-) diff --git a/components/BlurryPoster/BlurryPoster.styles.tsx b/components/BlurryPoster/BlurryPoster.styles.tsx index 932ff7b5..5510998e 100644 --- a/components/BlurryPoster/BlurryPoster.styles.tsx +++ b/components/BlurryPoster/BlurryPoster.styles.tsx @@ -2,7 +2,7 @@ import { cnb } from 'cnbuilder'; export const root = 'relative bg-no-repeat bg-cover overflow-hidden break-words'; -export const bgImage = 'absolute top-0 left-0 w-full h-full object-cover'; +export const bgImage = 'absolute top-0 left-0 size-full object-cover'; export const blurWrapper = ( addBgBlur?: boolean, @@ -10,7 +10,7 @@ export const blurWrapper = ( type?: 'hero' | 'poster', bgColor?: 'black' | 'white', ) => cnb( - 'relative w-full h-full z-10', { + 'relative size-full z-10', { 'backdrop-blur-md' : addBgBlur, 'lg:from-black-true/20 lg:to-black-true/70': type === 'poster' && addDarkOverlay && bgColor === 'black', 'lg:bg-none': type === 'poster' && bgColor === 'black' && !addDarkOverlay, diff --git a/components/Bookshelf/Book.tsx b/components/Bookshelf/Book.tsx index 828474d8..10ebccdf 100644 --- a/components/Bookshelf/Book.tsx +++ b/components/Bookshelf/Book.tsx @@ -38,7 +38,7 @@ export const Book = ({ // animate={{ backgroundColor: isOpen ? '#FF0088' : '#0055FF' }} className={cnb('group relative transition-colors mr-4 w-120 flex justify-center align-start shrink-0 rounded hocus-visible:underline decoration-white', buttonClassName)} > -
+
cnb( export const imageAspectRatio = 'aspect-w-6 aspect-h-5'; export const image = 'object-cover group-hocus-within:scale-105 transition-transform'; export const imageOverlay = (textOnLeft: boolean) => cnb( - 'hidden sm:block from-black-true/50 via-black-true/20 to-transparent via-20% sm:absolute w-full h-full sm:top-0 sm:left-0', + 'hidden sm:block from-black-true/50 via-black-true/20 to-transparent via-20% sm:absolute size-full sm:top-0 sm:left-0', textOnLeft ? 'bg-gradient-to-r' : 'bg-gradient-to-l', ); diff --git a/components/ChangemakerCard/ChangemakerCard.styles.ts b/components/ChangemakerCard/ChangemakerCard.styles.ts index a457fbda..11e74307 100644 --- a/components/ChangemakerCard/ChangemakerCard.styles.ts +++ b/components/ChangemakerCard/ChangemakerCard.styles.ts @@ -1,12 +1,12 @@ export const root = 'relative w-full max-w-[29rem] sm:max-w-300 lg:max-w-[35rem] mx-auto break-words'; -export const cardInner = 'relative w-full h-full aspect-w-1 aspect-h-2'; +export const cardInner = 'relative size-full aspect-w-1 aspect-h-2'; -export const cardFront = 'absolute w-full h-full top-0 left-0'; +export const cardFront = 'absolute size-full top-0 left-0'; export const imageWrapper = 'overflow-hidden aspect-w-1 aspect-h-2'; -export const info = 'rs-px-1 pb-150 absolute w-full h-full bottom-0 left-0 mb-0'; +export const info = 'rs-px-1 pb-150 absolute size-full bottom-0 left-0 mb-0'; export const heading = 'mb-02em mt-auto'; -export const cardContent = 'absolute w-full h-full top-0 left-0 px-20 py-30 3xl:py-48 3xl:px-36 aria-hidden:opacity-0 opacity-100 backdrop-blur-sm transition-opacity duration-500 bg-gradient-to-b from-gc-black/60 to-gc-black/90 gc-changemaker *:*:*:!mb-1em'; +export const cardContent = 'absolute size-full top-0 left-0 px-20 py-30 3xl:py-48 3xl:px-36 aria-hidden:opacity-0 opacity-100 backdrop-blur-sm transition-opacity duration-500 bg-gradient-to-b from-gc-black/60 to-gc-black/90 gc-changemaker *:*:*:!mb-1em'; -export const button = 'group absolute w-full h-full top-0 left-0'; +export const button = 'group absolute size-full top-0 left-0'; export const icon = 'absolute bottom-40 right-36 text-white w-65 h-65 border-2 border-white rounded-full p-16 group-hocus-visible:border-dashed group-aria-expanded:rotate-45 transition-transform'; diff --git a/components/FeaturedStories/FeatureMasonry.tsx b/components/FeaturedStories/FeatureMasonry.tsx index 6750842d..ce0224ea 100644 --- a/components/FeaturedStories/FeatureMasonry.tsx +++ b/components/FeaturedStories/FeatureMasonry.tsx @@ -53,7 +53,7 @@ export const FeatureMasonry = ({ )} overlay="black-10" /> -
+
-
+
{imageAlt1
cnb('absolute top-0 left-0 w-full h-full z-10', hasBgGradient ? 'bg-gradient-to-b via-50%' : ''); +export const bgImage = 'absolute top-0 left-0 size-full object-cover'; +export const overlay = (hasBgGradient?: boolean) => cnb('absolute top-0 left-0 size-full z-10', hasBgGradient ? 'bg-gradient-to-b via-50%' : ''); export const contentWrapper = '*:mx-auto'; export const superhead = 'relative z-10 xl:max-w-900 mx-auto rs-mb-0 text-shadow-sm'; diff --git a/components/Hero/StoryHero.styles.ts b/components/Hero/StoryHero.styles.ts index deb5175a..a43e88a3 100644 --- a/components/Hero/StoryHero.styles.ts +++ b/components/Hero/StoryHero.styles.ts @@ -85,10 +85,10 @@ export const imageWrapper = (isVerticalHero: boolean, isLeftImage: boolean) => c }); export const image = (renderTwoImages: boolean) => cnb( - 'w-full h-full', + 'size-full', renderTwoImages ? 'hidden lg:block' : '', ); -export const mobileImage = 'w-full h-full lg:hidden'; +export const mobileImage = 'size-full lg:hidden'; export const caption = (isVerticalHero: boolean, isLeftImage: boolean) => cnb('text-current rs-mt-0 cc type-0', { 'lg:pr-0': isVerticalHero && isLeftImage, diff --git a/components/Hero/StoryHeroMvp.styles.ts b/components/Hero/StoryHeroMvp.styles.ts index 8f778611..e147ca3a 100644 --- a/components/Hero/StoryHeroMvp.styles.ts +++ b/components/Hero/StoryHeroMvp.styles.ts @@ -22,9 +22,9 @@ export const mobileImageCrops = { }; export const image = (renderTwoImages: boolean) => cnb( - 'w-full h-full', + 'size-full', renderTwoImages ? 'hidden lg:block' : '', ); -export const mobileImage = 'w-full h-full lg:hidden'; +export const mobileImage = 'size-full lg:hidden'; export const captionWrapper = 'mt-06em'; export const caption = 'caption *:leading-display mt-08em max-w-prose-wide'; diff --git a/components/Homepage/BelowBlockBanner.tsx b/components/Homepage/BelowBlockBanner.tsx index 32cfe273..4eec04d5 100644 --- a/components/Homepage/BelowBlockBanner.tsx +++ b/components/Homepage/BelowBlockBanner.tsx @@ -3,7 +3,7 @@ import { Grid } from '../Grid'; export const BelowBlockBanner = ({ children }: { children: React.ReactNode }) => ( -
+
{children} diff --git a/components/Homepage/Changemaker.tsx b/components/Homepage/Changemaker.tsx index fad965e9..048d44d8 100644 --- a/components/Homepage/Changemaker.tsx +++ b/components/Homepage/Changemaker.tsx @@ -20,7 +20,7 @@ export const Changemaker = ({ style={{ backgroundImage: `url('${bgImage}')` }} py={10} > -
+
diff --git a/components/Homepage/HomepageSplitHero.styles.ts b/components/Homepage/HomepageSplitHero.styles.ts index 88b425c4..35e56abb 100644 --- a/components/Homepage/HomepageSplitHero.styles.ts +++ b/components/Homepage/HomepageSplitHero.styles.ts @@ -2,14 +2,14 @@ export const root = 'relative overflow-hidden'; export const imageGridWrapper = 'relative max-h-[180rem] bg-black-true pt-170 sm:pt-[24vw] 2xl:pt-[16vw] 4xl:pt-[32rem] pb-[50vw] sm:pb-[40vw] 2xl:pb-[36vw] 4xl:pb-[64rem]'; export const mobileBg = 'sm:hidden'; export const bg = 'hidden sm:block'; -export const gradientOverlay = 'absolute top-0 left-0 w-full h-full bg-gradient-to-bl from-[#001c36ab] via-transparent via-60%'; +export const gradientOverlay = 'absolute top-0 left-0 size-full bg-gradient-to-bl from-[#001c36ab] via-transparent via-60%'; export const imageGrid = 'relative w-11/12 sm:w-[70vw] mx-auto 4xl:max-w-[140rem]'; export const imageWrapper = 'relative w-full aspect-w-2 aspect-h-3 sm:aspect-w-1 sm:aspect-h-1'; -export const imageTopLayerCommon = 'absolute top-0 right-0 w-full h-full object-cover mix-blend-lighten -scale-x-100'; -export const imageBottomLayerCommon = 'w-full h-full object-cover'; +export const imageTopLayerCommon = 'absolute top-0 right-0 size-full object-cover mix-blend-lighten -scale-x-100'; +export const imageBottomLayerCommon = 'size-full object-cover'; -export const textFlexbox = 'absolute w-full h-full top-0 left-0 cc 3xl:px-100 4xl:px-[calc((100%-1800px)/2)]'; +export const textFlexbox = 'absolute size-full top-0 left-0 cc 3xl:px-100 4xl:px-[calc((100%-1800px)/2)]'; export const textWrapperTop = 'relative -top-60 sm:-top-[10vw] xl:-top-[8vw] 4xl:-top-[15rem] right-0'; export const textWrapperBottom = 'relative top-[12%]'; export const serifText = 'text-[clamp(2.5rem,2.74vw+1.51rem,7rem)]'; diff --git a/components/ImageOverlay.tsx b/components/ImageOverlay.tsx index 106b79c2..c2004723 100644 --- a/components/ImageOverlay.tsx +++ b/components/ImageOverlay.tsx @@ -43,13 +43,13 @@ export const ImageOverlay = ({ loading={loading} width={width} height={height} - className={cnb('absolute w-full h-full object-cover top-0 left-0', className)} + className={cnb('absolute size-full object-cover top-0 left-0', className)} {...props} /> {overlay && (
cnb('absolute top-0 left-0 w-full h-full z-10', hasBgGradient ? 'bg-gradient-to-b via-50%' : ''); +export const bgImage = 'absolute top-0 left-0 size-full object-cover'; +export const overlay = (hasBgGradient: boolean) => cnb('absolute top-0 left-0 size-full z-10', hasBgGradient ? 'bg-gradient-to-b via-50%' : ''); export const contentWrapper = 'lg:rs-pr-9 ml-0'; @@ -14,7 +14,7 @@ export const headingWrapper = 'mx-auto w-fit gap-02em'; export const thumbnailWrapper = 'inline-block'; export const thumbnail = 'size-[0.75em]'; -export const body = 'max-w-prose mx-auto rs-mt-3 *:*:text-center text-balance mb-0 *:*:text-shadow-sm'; +export const body = (isDarktheme: boolean) => cnb('max-w-prose mx-auto rs-mt-3 *:*:text-center text-balance mb-0', isDarktheme && 'text-shadow-sm'); export const cta = (isStackedCtas: boolean) => cnb( 'gap-27 mx-auto w-fit *:mx-auto rs-mt-4', !isStackedCtas && 'md:flex-row', diff --git a/components/MomentPoster/MomentPoster.tsx b/components/MomentPoster/MomentPoster.tsx index c21f7c80..eceb17b3 100644 --- a/components/MomentPoster/MomentPoster.tsx +++ b/components/MomentPoster/MomentPoster.tsx @@ -28,6 +28,7 @@ type MomentPosterProps = HTMLAttributes & { bgImageFocus?: string; thumbnailSrc?: string; thumbnailFocus?: string; + isDarkTheme?: boolean; gradientTop?: GradientToType; gradientBottom?: GradientFromType; gradientVia?: GradientViaType; @@ -46,6 +47,7 @@ export const MomentPoster = ({ bgImageFocus, thumbnailSrc, thumbnailFocus, + isDarkTheme, gradientTop, gradientBottom, gradientVia, @@ -57,7 +59,7 @@ export const MomentPoster = ({ const hasBgGradient = !!gradientTop && !!gradientBottom; return ( - + {!!bgImageSrc && ( {subhead} @@ -150,7 +152,7 @@ export const MomentPoster = ({ )} {body && ( - + {body} diff --git a/components/Scrollytelling/Scrollytelling.styles.ts b/components/Scrollytelling/Scrollytelling.styles.ts index 51fdc863..8e976e81 100644 --- a/components/Scrollytelling/Scrollytelling.styles.ts +++ b/components/Scrollytelling/Scrollytelling.styles.ts @@ -23,8 +23,8 @@ export type OverlayType = keyof typeof overlays; export const wrapper = 'relative'; export const imageWrapper = 'sticky top-0 h-screen w-full z-0'; -export const image = 'absolute w-full h-full object-cover top-0 left-0 z-0'; -export const imageOverlay = (overlay?: OverlayType) => cnb('absolute w-full h-full top-0 left-0 z-0 bg-black-true/50', overlays[overlay]); +export const image = 'absolute size-full object-cover top-0 left-0 z-0'; +export const imageOverlay = (overlay?: OverlayType) => cnb('absolute size-full top-0 left-0 z-0 bg-black-true/50', overlays[overlay]); export const content = 'relative z-10 cc text-white rs-py-10'; export const contentWrapper = (contentAlign: ContentAlignType) => cnb('w-full mx-auto md:w-2/3 xl:w-1/2', { diff --git a/components/Scrollytelling/ScrollytellingDemo.tsx b/components/Scrollytelling/ScrollytellingDemo.tsx index 1b675878..654975ad 100644 --- a/components/Scrollytelling/ScrollytellingDemo.tsx +++ b/components/Scrollytelling/ScrollytellingDemo.tsx @@ -95,14 +95,14 @@ export const ScrollytellingDemo = () => { Chapter 2
-
+
{section4InView && ( <>
{ @@ -147,7 +147,7 @@ export const ScrollytellingDemo = () => { muted loop aria-label="video of milky way rotating" - className="block w-full h-full object-cover" + className="block size-full object-cover" > diff --git a/components/StoryCard/StoryCard.styles.tsx b/components/StoryCard/StoryCard.styles.tsx index 2f295a4d..5734ce77 100644 --- a/components/StoryCard/StoryCard.styles.tsx +++ b/components/StoryCard/StoryCard.styles.tsx @@ -16,7 +16,7 @@ export const cardWrapper = (isHorizontal: boolean) => cnb( export const imageWrapper = 'transition-all aspect-w-1 aspect-h-1 overflow-hidden'; -export const image = 'object-cover w-full h-full group-hocus-within:scale-105 transition-transform'; +export const image = 'object-cover size-full group-hocus-within:scale-105 transition-transform'; export const contentWrapper = (isHorizontal: boolean) => cnb({ 'rs-pr-4 rs-py-4': isHorizontal, diff --git a/components/StoryImage/StoryImage.styles.ts b/components/StoryImage/StoryImage.styles.ts index 4521d600..afa14045 100644 --- a/components/StoryImage/StoryImage.styles.ts +++ b/components/StoryImage/StoryImage.styles.ts @@ -20,5 +20,5 @@ export const root = (isFullHeight?: boolean) => cnb(isFullHeight ? 'h-full' : '' export const animateWrapper = (isFullHeight?: boolean) => cnb(isFullHeight ? 'h-full' : ''); export const figure = (isFullHeight?: boolean) => cnb(isFullHeight ? 'h-full' : ''); export const imageWrapper = (isFullHeight?: boolean) => cnb(isFullHeight ? 'h-full' : ''); -export const image = 'w-full h-full object-cover'; +export const image = 'size-full object-cover'; export const caption = '*:*:leading-display caption mt-1em max-w-prose-wide'; diff --git a/components/StoryPoC/BrochureChapter2.tsx b/components/StoryPoC/BrochureChapter2.tsx index b6a4cb59..fbed5ad3 100644 --- a/components/StoryPoC/BrochureChapter2.tsx +++ b/components/StoryPoC/BrochureChapter2.tsx @@ -24,7 +24,7 @@ export const BrochureChapter2 = () => {
@@ -80,7 +80,7 @@ export const BrochureChapter2 = () => {
@@ -91,7 +91,7 @@ export const BrochureChapter2 = () => {
@@ -124,7 +124,7 @@ export const BrochureChapter2 = () => {
diff --git a/components/StoryPoC/BrochureStory.tsx b/components/StoryPoC/BrochureStory.tsx index 1db8feb0..6e7aa316 100644 --- a/components/StoryPoC/BrochureStory.tsx +++ b/components/StoryPoC/BrochureStory.tsx @@ -59,7 +59,7 @@ export const BrochureStory = () => {
@@ -116,7 +116,7 @@ export const BrochureStory = () => {
diff --git a/components/StoryPoC/ProgressStory.tsx b/components/StoryPoC/ProgressStory.tsx index 00446790..975d6881 100644 --- a/components/StoryPoC/ProgressStory.tsx +++ b/components/StoryPoC/ProgressStory.tsx @@ -14,7 +14,7 @@ export const ProgressStory = () => { src={getProcessedImage('https://a-us.storyblok.com/f/1005200/1901x1643/e36a942af8/progress-dish-cropped.jpg', '2000x0')} alt="" loading="eager" - className="absolute w-full h-full object-cover object-top top-0 left-0" + className="absolute size-full object-cover object-top top-0 left-0" /> @@ -37,10 +37,10 @@ export const ProgressStory = () => { src={getProcessedImage('https://a-us.storyblok.com/f/1005200/4000x2250/0c54166208/vlad-hilitanu-pt7qzb4zlww-unsplash.jpg', '2000x2000')} alt="" loading="eager" - className="relative w-full h-full object-cover object-top" + className="relative size-full object-cover object-top" />
@@ -87,10 +87,10 @@ export const ProgressStory = () => { src={getProcessedImage('https://a-us.storyblok.com/f/1005200/2100x1350/02b8df40d3/21664-12-0011_cmyk-1.jpg', '2000x1200')} alt="" loading="eager" - className="relative w-full h-full object-cover object-top" + className="relative size-full object-cover object-top" />
diff --git a/components/StoryPoC/VideoScrollStory.tsx b/components/StoryPoC/VideoScrollStory.tsx index 8b1f362a..68efe6f8 100644 --- a/components/StoryPoC/VideoScrollStory.tsx +++ b/components/StoryPoC/VideoScrollStory.tsx @@ -28,7 +28,7 @@ export const VideoScrollStory = () => { muted loop aria-label="Background Video" - className="block w-full h-full object-cover" + className="block size-full object-cover" > @@ -36,9 +36,9 @@ export const VideoScrollStory = () => { -
+
diff --git a/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts index d41e6417..15907e97 100644 --- a/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts +++ b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.styles.ts @@ -1,12 +1,12 @@ import { cnb } from 'cnbuilder'; export const root = 'relative overflow-hidden'; -export const bgImage = 'absolute top-0 left-0 w-full h-full object-cover'; -export const overlay = (hasBgGradient?: boolean) => cnb('absolute top-0 left-0 w-full h-full z-10', hasBgGradient ? 'bg-gradient-to-b' : ''); +export const bgImage = 'absolute top-0 left-0 size-full object-cover'; +export const overlay = (hasBgGradient: boolean) => cnb('absolute top-0 left-0 size-full z-10', hasBgGradient ? 'bg-gradient-to-b' : ''); export const header = 'relative overflow-hidden cc 3xl:px-100 4xl:px-[calc((100%-1800px)/2)] z-20'; -export const superhead = 'text-shadow-sm'; +export const superhead = (isDarkTheme: boolean) => isDarkTheme && 'text-shadow-sm'; export const heading = 'fluid-type-7 md:gc-splash mb-0 whitespace-pre-line'; export const introWrapper = 'cc relative z-20'; -export const intro = 'intro-text *:leading-display *:md:leading-cozy *:text-shadow-sm rs-mt-7 max-w-1000'; +export const intro = (isDarkTheme: boolean) => cnb('intro-text *:leading-display *:md:leading-cozy rs-mt-7 max-w-1000', isDarkTheme && 'text-shadow-sm'); export const contentWrapper = 'relative z-20'; export const cta = 'relative cc md:flex-row *:mx-auto rs-mt-6 gap-20 lg:gap-27 w-fit'; diff --git a/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.tsx b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.tsx index 10959e16..ec63c0b4 100644 --- a/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.tsx +++ b/components/Storyblok/SbHomepageThemeSection/SbHomepageThemeSection.tsx @@ -12,7 +12,14 @@ import { getProcessedImage } from '@/utilities/getProcessedImage'; import { hasRichText } from '@/utilities/hasRichText'; import * as styles from './SbHomepageThemeSection.styles'; import { - bgBlurs, type BgBlurType, gradientFroms, type GradientFromType, gradientTos, type GradientToType, + gradientFroms, + type GradientFromType, + gradientTos, + type GradientToType, + gradientVias, + type GradientViaType, + bgBlurs, + type BgBlurType, } from '@/utilities/datasource'; import { getNumBloks } from '@/utilities/getNumBloks'; @@ -24,10 +31,12 @@ type SbHomepageThemeSectionProps = { intro?: StoryblokRichtext; content?: SbBlokData[]; cta?: SbBlokData[]; + isDarkTheme?: boolean; bgImage?: SbImageType; bgBlur?: BgBlurType; gradientTop?: GradientToType; gradientBottom?: GradientFromType; + gradientVia?: GradientViaType; }; }; @@ -38,10 +47,12 @@ export const SbHomepageThemeSection = ({ intro, content, cta, + isDarkTheme, bgImage: { filename, focus } = {}, bgBlur, gradientTop, gradientBottom, + gradientVia, }, blok, }: SbHomepageThemeSectionProps) => { @@ -50,7 +61,7 @@ export const SbHomepageThemeSection = ({ return ( )} @@ -111,7 +123,8 @@ export const SbHomepageThemeSection = ({ leading="tight" font="serif" weight="semibold" - className={styles.superhead} + color={isDarkTheme ? 'white' : 'black'} + className={styles.superhead(isDarkTheme)} aria-hidden={!!heading} > {superhead} @@ -123,6 +136,7 @@ export const SbHomepageThemeSection = ({ leading="none" uppercase font="druk" + color={isDarkTheme ? 'white' : 'black'} className={styles.heading} > {superhead && {`${superhead}:`}}{heading} @@ -133,13 +147,13 @@ export const SbHomepageThemeSection = ({ )} - + {!!getNumBloks(cta) && ( diff --git a/components/Storyblok/SbMomentPoster.tsx b/components/Storyblok/SbMomentPoster.tsx index 6c020f40..39048c7a 100644 --- a/components/Storyblok/SbMomentPoster.tsx +++ b/components/Storyblok/SbMomentPoster.tsx @@ -24,6 +24,7 @@ type SbMomentPosterProps = { cta?: SbBlokData[]; bgImage?: SbImageType; thumbnail?: SbImageType; + isDarkTheme?: boolean; gradientTop?: GradientToType; gradientBottom?: GradientFromType; gradientVia?: GradientViaType; @@ -42,6 +43,7 @@ export const SbMomentPoster = ({ cta, bgImage: { filename, focus } = {}, thumbnail: { filename: thumbnailFilename, focus: thumbnailFocus } = {}, + isDarkTheme, gradientTop, gradientBottom, gradientVia, @@ -51,7 +53,7 @@ export const SbMomentPoster = ({ blok, }: SbMomentPosterProps) => { const Cta = !!getNumBloks(cta) ? : undefined; - const Body = hasRichText(body) ? : undefined; + const Body = hasRichText(body) ? : undefined; return ( cnb('relative z-10 rs-mt-3 ' export const contentWrapper = 'relative z-10'; export const cta = 'cc md:flex-row *:mx-auto rs-mt-3 gap-20 lg:gap-27 w-fit'; export const caption = 'caption *:leading-display mt-08em max-w-prose-wide'; + +export const bgImage = 'absolute top-0 left-0 size-full object-cover'; +export const overlay = (hasBgGradient?: boolean) => cnb('absolute top-0 left-0 size-full z-10', hasBgGradient ? 'bg-gradient-to-b via-50%' : ''); diff --git a/components/Storyblok/SbSection/SbSection.tsx b/components/Storyblok/SbSection/SbSection.tsx index f08644ae..2e677445 100644 --- a/components/Storyblok/SbSection/SbSection.tsx +++ b/components/Storyblok/SbSection/SbSection.tsx @@ -24,6 +24,16 @@ import { type SbImageType, type SbColorStopProps } from '../Storyblok.types'; import { getProcessedImage } from '@/utilities/getProcessedImage'; import { hasRichText } from '@/utilities/hasRichText'; import { getNumBloks } from '@/utilities/getNumBloks'; +import { + gradientFroms, + type GradientFromType, + gradientTos, + type GradientToType, + gradientVias, + type GradientViaType, + bgBlurs, + type BgBlurType, +} from '@/utilities/datasource'; import * as styles from './SbSection.styles'; type SbSectionProps = { @@ -45,6 +55,10 @@ type SbSectionProps = { } bgColor?: BgColorType; bgImage?: SbImageType; + gradientTop?: GradientToType; + gradientBottom?: GradientFromType; + gradientVia?: GradientViaType; + bgBlur?: BgBlurType; bgColorStops?: SbColorStopProps[]; paddingTop?: PaddingType; paddingBottom?: PaddingType; @@ -69,6 +83,10 @@ export const SbSection = ({ barColor: { value: barColorValue } = {}, bgColor, bgImage: { filename, focus } = {}, + gradientTop, + gradientBottom, + gradientVia, + bgBlur, bgColorStops, paddingTop, paddingBottom, @@ -78,6 +96,8 @@ export const SbSection = ({ blok, }: SbSectionProps) => { const hasHeader = heading || superhead || subheading; + // To render a dark overlay, both a top and bottom gradient color must be selected + const hasBgGradient = !!gradientTop && !!gradientBottom; const ref = useRef(null); const stops = []; @@ -126,10 +146,52 @@ export const SbSection = ({ pb={paddingBottom} className={styles.wrapper} > - {filename && ( - + + + + + + + )} + {/* Render the overlay if there's a background image, and if background blur or/and gradient is selected */} + {!!filename && (bgBlur !== 'none' || hasBgGradient) && ( +
)} {(heading || superhead) && ( @@ -174,7 +236,7 @@ export const SbSection = ({ font={isSerifHeader ? 'serif' : 'sans'} weight={isSerifHeader ? 'semibold' : 'normal'} align={headerAlign} - color={bgColor === 'black' ? 'black-20' : 'black-80'} + color={bgColor === 'black' ? 'black-20' : 'black-90'} noMargin className={styles.subhead(headerAlign)} > diff --git a/components/Temporary/DemoContent.tsx b/components/Temporary/DemoContent.tsx index bff9202b..2254fed3 100644 --- a/components/Temporary/DemoContent.tsx +++ b/components/Temporary/DemoContent.tsx @@ -10,7 +10,7 @@ export const DemoContent = () => (
-
+
To infinity and beyond @@ -117,7 +117,7 @@ export const DemoContent = () => (
-
+
); diff --git a/components/ThemeCard/ThemeCard.styles.tsx b/components/ThemeCard/ThemeCard.styles.tsx index bd28ff74..b328998b 100644 --- a/components/ThemeCard/ThemeCard.styles.tsx +++ b/components/ThemeCard/ThemeCard.styles.tsx @@ -4,7 +4,7 @@ export const cardWrapper = 'group relative'; export const imageWrapper = 'transition-all aspect-w-1 aspect-h-1 overflow-hidden'; -export const image = 'object-cover w-full h-full group-hocus-within:scale-105 transition-transform'; +export const image = 'object-cover size-full group-hocus-within:scale-105 transition-transform'; export const heading = 'mt-06em rs-mb-neg1 text-current'; diff --git a/components/Typography/typography.styles.ts b/components/Typography/typography.styles.ts index bd882d44..dc9ea56c 100644 --- a/components/Typography/typography.styles.ts +++ b/components/Typography/typography.styles.ts @@ -62,6 +62,7 @@ export const textColors = { 'black-40': 'text-black-40', 'black-60': 'text-black-60', 'black-80': 'text-black-80', + 'black-90': 'text-black-90', }; export const textVariants = { diff --git a/components/VerticalPoster/VerticalPoster.styles.ts b/components/VerticalPoster/VerticalPoster.styles.ts index da66160b..eb8a4aeb 100644 --- a/components/VerticalPoster/VerticalPoster.styles.ts +++ b/components/VerticalPoster/VerticalPoster.styles.ts @@ -1,7 +1,7 @@ import { cnb } from 'cnbuilder'; export const root = 'relative overflow-hidden break-words'; -export const blurWrapper = 'w-full h-full backdrop-blur-md'; +export const blurWrapper = 'size-full backdrop-blur-md'; export const grid = 'w-full'; diff --git a/utilities/datasource.ts b/utilities/datasource.ts index 9e8adada..5e9872bc 100644 --- a/utilities/datasource.ts +++ b/utilities/datasource.ts @@ -79,6 +79,16 @@ export const gradientTos = { 'black-80': 'to-black-true/80', 'black-90': 'to-black-true/90', 'gc-black': 'to-gc-black', + 'white-10': 'to-white/10', + 'white-20': 'to-white/20', + 'white-30': 'to-white/30', + 'white-40': 'to-white/40', + 'white-50': 'to-white/50', + 'white-60': 'to-white/60', + 'white-70': 'to-white/70', + 'white-80': 'to-white/80', + 'white-90': 'to-white/90', + white: 'to-white', }; export type GradientToType = keyof typeof gradientTos; @@ -94,6 +104,16 @@ export const gradientFroms = { 'black-80': 'from-black-true/80', 'black-90': 'from-black-true/90', 'gc-black': 'from-gc-black', + 'white-10': 'from-white/10', + 'white-20': 'from-white/20', + 'white-30': 'from-white/30', + 'white-40': 'from-white/40', + 'white-50': 'from-white/50', + 'white-60': 'from-white/60', + 'white-70': 'from-white/70', + 'white-80': 'from-white/80', + 'white-90': 'from-white/90', + white: 'from-white', }; export type GradientFromType = keyof typeof gradientFroms; @@ -109,6 +129,16 @@ export const gradientVias = { 'black-80': 'via-black-true/80', 'black-90': 'via-black-true/90', 'gc-black': 'via-gc-black', + 'white-10': 'via-white/10', + 'white-20': 'via-white/20', + 'white-30': 'via-white/30', + 'white-40': 'via-white/40', + 'white-50': 'via-white/50', + 'white-60': 'via-white/60', + 'white-70': 'via-white/70', + 'white-80': 'via-white/80', + 'white-90': 'via-white/90', + white: 'via-white', }; export type GradientViaType = keyof typeof gradientVias; From 5d0707868dbdf9d2f54f1d24d2b7929f3dd1cc5a Mon Sep 17 00:00:00 2001 From: Github Action Date: Mon, 18 Mar 2024 23:50:22 +0000 Subject: [PATCH 29/34] 1.3.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3d324aba..a91728d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ood-giving-campaign", - "version": "1.3.0", + "version": "1.3.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ood-giving-campaign", - "version": "1.3.0", + "version": "1.3.1", "dependencies": { "@heroicons/react": "^2.1.1", "@storyblok/react": "^3.0.8", diff --git a/package.json b/package.json index 2f616779..a04ba757 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ood-giving-campaign", - "version": "1.3.0", + "version": "1.3.1", "description": "Momentum", "author": "Stanford University", "keywords": [ From cec029a90e9e35689171037645ee3f6b58acad8c Mon Sep 17 00:00:00 2001 From: Yvonne Tang <42749717+yvonnetangsu@users.noreply.github.com> Date: Tue, 19 Mar 2024 16:20:38 -0700 Subject: [PATCH 30/34] GIVCAMP-307 | Stacked story hero variant (#251) * Stacked story hero variant * hero headline sizes * Hero variant styles * Stretch image to full width * Optimize images; clean up * Add fallback hero bg color before a proper value is entered --- components/BlurryPoster/BlurryPoster.tsx | 81 +++++------ components/Hero/StoryHeroMvp.styles.ts | 27 ---- components/Hero/StoryHeroMvp.tsx | 81 ++++++----- components/Hero/StoryHeroStacked.styles.ts | 21 +++ components/Hero/StoryHeroStacked.tsx | 130 ++++++++++++++++++ components/Hero/index.ts | 1 + .../Storyblok/SbStoryMvp/SbStoryMvp.tsx | 4 + components/Storyblok/Storyblok.types.ts | 5 + 8 files changed, 249 insertions(+), 101 deletions(-) create mode 100644 components/Hero/StoryHeroStacked.styles.ts create mode 100644 components/Hero/StoryHeroStacked.tsx diff --git a/components/BlurryPoster/BlurryPoster.tsx b/components/BlurryPoster/BlurryPoster.tsx index 82ab4356..39137274 100644 --- a/components/BlurryPoster/BlurryPoster.tsx +++ b/components/BlurryPoster/BlurryPoster.tsx @@ -93,42 +93,44 @@ export const BlurryPoster = ({ return ( - - - - - - {bgImageAlt - + {bgImageSrc && ( + + + + + + {bgImageAlt + + )}
)} - {/* No authors and published dates for MVP */} - {/* {byline && ( - {byline} - )} - {date && ( - - )} */} {cta && (
{cta} diff --git a/components/Hero/StoryHeroMvp.styles.ts b/components/Hero/StoryHeroMvp.styles.ts index e147ca3a..147c2407 100644 --- a/components/Hero/StoryHeroMvp.styles.ts +++ b/components/Hero/StoryHeroMvp.styles.ts @@ -1,30 +1,3 @@ -import { cnb } from 'cnbuilder'; - export const root = 'relative'; - -export const imageCrops = { - '1x1': '1200x1200', - '2x1': '2000x1000', - '3x2': '2100x1400', - '5x8': '1000x1600', - '16x9': '2000x1125', - 'free': '2000x0', -}; -export type ImageCropType = keyof typeof imageCrops; - -export const mobileImageCrops = { - '1x1': '1000x1000', - '2x1': '1000x500', - '3x2': '1200x800', - '5x8': '1000x1600', - '16x9': '1600x900', - 'free': '1000x0', -}; - -export const image = (renderTwoImages: boolean) => cnb( - 'size-full', - renderTwoImages ? 'hidden lg:block' : '', -); -export const mobileImage = 'size-full lg:hidden'; export const captionWrapper = 'mt-06em'; export const caption = 'caption *:leading-display mt-08em max-w-prose-wide'; diff --git a/components/Hero/StoryHeroMvp.tsx b/components/Hero/StoryHeroMvp.tsx index e41b5d6a..fdb593d7 100644 --- a/components/Hero/StoryHeroMvp.tsx +++ b/components/Hero/StoryHeroMvp.tsx @@ -3,12 +3,13 @@ import { Container } from '@/components/Container'; import { BlurryPoster } from '@/components/BlurryPoster'; import { CreateBloks } from '@/components/CreateBloks'; import { RichText } from '@/components/RichText'; -import { type SbImageType, type SbTypographyProps } from '@/components/Storyblok/Storyblok.types'; +import { StoryHeroStacked } from '@/components/Hero/StoryHeroStacked'; +import { type SbImageType, type SbTypographyProps, type SbColorPickerType } from '@/components/Storyblok/Storyblok.types'; import { type SbBlokData } from '@storyblok/react/rsc'; import { paletteAccentColors, type PaletteAccentHexColorType } from '@/utilities/colorPalettePlugin'; import { getNumBloks } from '@/utilities/getNumBloks'; import { hasRichText } from '@/utilities/hasRichText'; -import{ type HeroOverlayType } from '@/utilities/datasource'; +import { type HeroOverlayType } from '@/utilities/datasource'; import * as styles from './StoryHeroMvp.styles'; export type StoryHeroMvpProps = { @@ -20,6 +21,8 @@ export type StoryHeroMvpProps = { byline?: string; publishedDate?: string; dek?: string; + heroVariant?: 'default' | 'stacked'; + heroBgColor?: SbColorPickerType; heroImage?: SbImageType; bgImage?: SbImageType; bgImageAlt?: string; @@ -46,6 +49,8 @@ export const StoryHeroMvp = ({ byline, dek, publishedDate, + heroVariant, + heroBgColor: { color: bgHexColor } = {}, heroImage: { filename, focus } = {}, bgImage: { filename: bgImageSrc, focus: bgImageFocus } = {}, bgImageAlt, @@ -67,10 +72,8 @@ export const StoryHeroMvp = ({ day: 'numeric', year: 'numeric', }); - - const Caption = hasRichText(caption) - ? - : undefined; + const hasCaption = hasRichText(caption); + const Caption = hasCaption ? : undefined; return ( - + {heroVariant === 'stacked' ? ( + + ) : ( + + )} {!!getNumBloks(heroTexturedBar) && ( )} diff --git a/components/Hero/StoryHeroStacked.styles.ts b/components/Hero/StoryHeroStacked.styles.ts new file mode 100644 index 00000000..9e9d3a96 --- /dev/null +++ b/components/Hero/StoryHeroStacked.styles.ts @@ -0,0 +1,21 @@ +import { cnb } from 'cnbuilder'; + +export const root = 'relative'; + +export const contentWrapper = 'mt-40 md:-mt-60 xl:mt-0'; +export const superhead = (isLightHero: boolean) => cnb('cc mb-04em w-full', !isLightHero && 'text-shadow-sm'); +export const heading = ( + isSmallHeading?: boolean, + headingFont?: 'druk' | 'serif', +) => cnb('mb-0 text-balance mx-auto whitespace-pre-line', { + 'fluid-type-7 max-w-1400': headingFont === 'druk', + 'md:fluid-type-8': isSmallHeading && headingFont === 'druk', + 'md:fluid-type-9': !isSmallHeading && headingFont === 'druk', + 'fluid-type-5 md:fluid-type-7 max-w-1200': headingFont === 'serif', + 'xl:fluid-type-8 ': headingFont === 'serif' && !isSmallHeading, +}); +export const dek = 'max-w-900 text-balance mx-auto rs-mt-3'; +export const image = 'rs-mt-4 w-full'; +export const mobileImage = 'size-full lg:hidden'; +export const captionWrapper = 'mt-06em'; +export const caption = 'caption *:leading-display mt-08em max-w-prose-wide'; diff --git a/components/Hero/StoryHeroStacked.tsx b/components/Hero/StoryHeroStacked.tsx new file mode 100644 index 00000000..4831df2c --- /dev/null +++ b/components/Hero/StoryHeroStacked.tsx @@ -0,0 +1,130 @@ +import { AnimateInView } from '@/components/Animate'; +import { Container } from '@/components/Container'; +import { + Heading, Paragraph, Text, SrOnlyText, +} from '@/components/Typography'; +import { getProcessedImage } from '@/utilities/getProcessedImage'; +import { getSbImageSize } from '@/utilities/getSbImageSize'; +import * as styles from './StoryHeroStacked.styles'; + +export type StoryHeroStackedProps = { + title: string; + superhead?: string; + headingFont?: 'serif' | 'druk'; + isSmallHeading?: boolean; + dek?: string; + heroBgColor?: string; // Hex color value from Storyblok native color picker + imageSrc?: string; + imageFocus?: string; + alt?: string; + hasCaption?: boolean; + isLightHero?: boolean; +}; + +export const StoryHeroStacked = ({ + title, + superhead, + headingFont, + isSmallHeading, + dek, + heroBgColor, + imageSrc, + imageFocus, + alt, + hasCaption, + isLightHero = false, +}: StoryHeroStackedProps) => { + // We keep the original image aspect ratio + const imageSize = getSbImageSize(imageSrc) || { width: 0, height: 0 }; + const { width: imageWidth, height: imageHeight } = imageSize; + + return ( + + + {superhead && ( + + + {superhead} + + + )} + {title && ( + + + {superhead && {`${superhead}:`}}{title} + + + )} + {dek && ( + + + {dek} + + + )} + + {imageSrc && ( + + + + + + + + {alt + + + )} + + ); +}; diff --git a/components/Hero/index.ts b/components/Hero/index.ts index d49cde69..6475fd2d 100644 --- a/components/Hero/index.ts +++ b/components/Hero/index.ts @@ -2,3 +2,4 @@ export * from './Hero'; export * from './BasicHero'; export * from './StoryHero'; export * from './StoryHeroMvp'; +export * from './StoryHeroStacked'; diff --git a/components/Storyblok/SbStoryMvp/SbStoryMvp.tsx b/components/Storyblok/SbStoryMvp/SbStoryMvp.tsx index 4e675db2..b1cbaddf 100644 --- a/components/Storyblok/SbStoryMvp/SbStoryMvp.tsx +++ b/components/Storyblok/SbStoryMvp/SbStoryMvp.tsx @@ -30,6 +30,8 @@ export const SbStoryMvp = ({ byline, dek, publishedDate, + heroVariant, + heroBgColor, heroImage, bgImage, bgImageAlt, @@ -70,6 +72,8 @@ export const SbStoryMvp = ({ dek={dek} byline={byline} publishedDate={publishedDate} + heroVariant={heroVariant} + heroBgColor={heroBgColor} heroImage={heroImage} bgImage={bgImage} bgImageAlt={bgImageAlt} diff --git a/components/Storyblok/Storyblok.types.ts b/components/Storyblok/Storyblok.types.ts index de2aab84..716215b7 100644 --- a/components/Storyblok/Storyblok.types.ts +++ b/components/Storyblok/Storyblok.types.ts @@ -50,3 +50,8 @@ export type SbColorStopProps = { stop: string; hexColor: string; }; + +// Storyblok Native Color Picker +export type SbColorPickerType = { + color?: string; +}; From 147fad95555f324a33d4859b82580092a5094b9d Mon Sep 17 00:00:00 2001 From: Github Action Date: Tue, 19 Mar 2024 23:35:28 +0000 Subject: [PATCH 31/34] 1.3.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a91728d5..0a2134b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ood-giving-campaign", - "version": "1.3.1", + "version": "1.3.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ood-giving-campaign", - "version": "1.3.1", + "version": "1.3.2", "dependencies": { "@heroicons/react": "^2.1.1", "@storyblok/react": "^3.0.8", diff --git a/package.json b/package.json index a04ba757..a51df6e5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ood-giving-campaign", - "version": "1.3.1", + "version": "1.3.2", "description": "Momentum", "author": "Stanford University", "keywords": [ From 319c511c5c7cc0c6dd6d9da6a964576ceb4deb7b Mon Sep 17 00:00:00 2001 From: Sherakama Date: Thu, 21 Mar 2024 11:30:23 -0700 Subject: [PATCH 32/34] Update robots to use different URL for sitemap path (#254) --- app/robots.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/robots.ts b/app/robots.ts index 9a01b816..55b669ec 100644 --- a/app/robots.ts +++ b/app/robots.ts @@ -1,7 +1,7 @@ import { MetadataRoute } from 'next'; export default function robots(): MetadataRoute.Robots { - const CurrentURL = process.env.DEPLOY_PRIME_URL || 'http://localhost:3000'; + const CurrentURL = process.env.URL || process.env.DEPLOY_PRIME_URL || 'https://momentum.stanford.edu'; return { rules: { userAgent: '*', @@ -9,4 +9,4 @@ export default function robots(): MetadataRoute.Robots { }, sitemap: CurrentURL + '/sitemap.xml', }; -} \ No newline at end of file +} From d07d5bd0a8496163e2467ddf3df20a1cdd3a5a23 Mon Sep 17 00:00:00 2001 From: Github Action Date: Thu, 21 Mar 2024 18:36:44 +0000 Subject: [PATCH 33/34] 1.3.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0a2134b7..9b659b37 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ood-giving-campaign", - "version": "1.3.2", + "version": "1.3.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ood-giving-campaign", - "version": "1.3.2", + "version": "1.3.3", "dependencies": { "@heroicons/react": "^2.1.1", "@storyblok/react": "^3.0.8", diff --git a/package.json b/package.json index a51df6e5..76f56a61 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ood-giving-campaign", - "version": "1.3.2", + "version": "1.3.3", "description": "Momentum", "author": "Stanford University", "keywords": [ From fab0f2dc677296c94f2ee2a70b5b9383222d2c3d Mon Sep 17 00:00:00 2001 From: Yvonne Tang <42749717+yvonnetangsu@users.noreply.github.com> Date: Mon, 1 Apr 2024 11:52:59 -0700 Subject: [PATCH 34/34] GIVCAMP-292 GIVCAMP-305 | Horizontal Initiative card and image aspect ratio options (#256) * Image aspect ratio option * WIP styles horizontal card * WIp styles * section intro color light mode update; moment poster body line height update; horizontal initiative card styles * fixups * Cta update * Update maxwidth * Use size-full * doc * Adjust the max width a bit more --- .../InitiativeCard/InitiativeCard.styles.ts | 30 +++++++++++--- components/InitiativeCard/InitiativeCard.tsx | 41 ++++++++++++++----- .../MomentPoster/MomentPoster.styles.ts | 2 +- components/Storyblok/SbInitiativeCard.tsx | 8 +++- components/Storyblok/SbSection/SbSection.tsx | 2 +- 5 files changed, 64 insertions(+), 19 deletions(-) diff --git a/components/InitiativeCard/InitiativeCard.styles.ts b/components/InitiativeCard/InitiativeCard.styles.ts index 7a44f78d..5b054fd8 100644 --- a/components/InitiativeCard/InitiativeCard.styles.ts +++ b/components/InitiativeCard/InitiativeCard.styles.ts @@ -1,24 +1,42 @@ import { cnb } from 'cnbuilder'; -export const root = 'group relative size-full @container'; +export type InitiativeCardImageAspectRatio = '3x4' | '1x1'; -export const topWrapper = 'relative @320:text-18 @sm:text-21 @md:text-23'; +export const root = (isHorizontal: boolean) => cnb('group relative size-full max-w-600 mx-auto', { + 'xl:flex-row xl:max-w-[124.2rem]': isHorizontal, // 1242px is the width of 10 of 12 columns at 2XL + '2xl:max-w-700': !isHorizontal, +}); + +export const topWrapper = (isHorizontal: boolean) => cnb('relative @320:text-18 @sm:text-21 @md:text-23', { + 'xl:basis-1/2': isHorizontal, +}); -export const imageWrapper = 'bg-gc-black transition-all aspect-w-1 aspect-h-1 sm:aspect-w-3 sm:aspect-h-4 overflow-hidden'; +export const imageWrapper = (imageAspectRatio: InitiativeCardImageAspectRatio) => cnb('bg-gc-black aspect-w-1 aspect-h-1 size-full overflow-hidden', { + 'sm:aspect-w-3 sm:aspect-h-4': imageAspectRatio === '3x4', +}); export const image = 'object-cover backface-hidden size-full group-hocus-within:scale-105 transition-transform will-change-transform'; -export const heading = 'absolute bottom-0 w-full bg-black-true/60 text-white rs-p-1 mb-0 group-hocus-within:bg-black-true/70 group-hocus-within:border-y-4 border-transparent group-hocus-within:border-white transition-all text-shadow-sm group-hocus-within:rs-py-2'; +export const heading = (isHorizontal: boolean) => cnb('absolute bottom-0 w-full bg-black-true/60 text-white mb-0 group-hocus-within:bg-black-true/60 border-transparent group-hocus-within:border-white transition-all text-shadow-sm rs-p-1 group-hocus-within:rs-py-2', { + 'group-hocus-within:border-y-4': !isHorizontal, + 'xl:rs-px-3 xl:rs-py-2 xl:group-hocus-within:rs-py-3 group-hocus-within:border-y-4 xl:group-hocus-within:border-b-0': isHorizontal, +}); -export const bodyWrapper = 'grow bg-gc-black text-black-10 rs-pt-2 rs-pr-1 @320:text-18 @sm:text-21 @md:text-23'; +export const bodyWrapper = (isHorizontal: boolean) => cnb('@container grow bg-gc-black text-black-10 rs-pt-2 rs-pr-1 @320:text-18 @sm:text-21 @md:text-23', { + 'xl:basis-1/2 flex flex-col justify-center': isHorizontal, +}); export const body = (hasTabColor: boolean) => cnb('rs-pl-1 text-current', { 'border-l-[1.4rem] md:border-l-[2rem]': hasTabColor, }); -export const cta = 'group/cta inline-block bg-gc-black text-white hocus:text-white stretched-link no-underline hocus:no-underline rs-py-1 rs-pr-1'; +export const cta = (isHorizontal: boolean) => cnb('group/cta inline-block bg-gc-black text-white hocus:text-white stretched-link no-underline hocus:no-underline rs-py-1 rs-pr-1', { + 'xl:hidden': isHorizontal, +}); export const linkText = 'text-19 md:text-25 mr-0 ml-auto last:children:underline'; export const lastword = 'underline decoration-digital-red-light underline-offset-4 group-hocus/cta:decoration-white'; export const icon = (hasLinkText?: boolean) => cnb('inline-block mb-0 mt-auto w-20 md:w-24 mr-0', hasLinkText? 'ml-10' : 'ml-auto', ); + +export const horizontalCta = 'stretched-link mx-auto rs-mt-2 hidden xl:block'; diff --git a/components/InitiativeCard/InitiativeCard.tsx b/components/InitiativeCard/InitiativeCard.tsx index 7678bcfc..918e3210 100644 --- a/components/InitiativeCard/InitiativeCard.tsx +++ b/components/InitiativeCard/InitiativeCard.tsx @@ -11,6 +11,7 @@ import { getProcessedImage } from '@/utilities/getProcessedImage'; import { accentBorderColors, type AccentBorderColorType } from '@/utilities/datasource'; import * as styles from './InitiativeCard.styles'; import { IconType } from '../HeroIcon'; +import { image } from '../Banner'; export type InitiativeCardProps = HTMLAttributes & { heading?: string; @@ -18,7 +19,9 @@ export type InitiativeCardProps = HTMLAttributes & { body?: string; imageSrc?: string; imageFocus?: string; + imageAspectRatio?: styles.InitiativeCardImageAspectRatio; tabColor?: AccentBorderColorType; + isHorizontal?: boolean; linkText?: string; link?: SbLinkType; animation?: AnimationType; @@ -31,7 +34,9 @@ export const InitiativeCard = ({ body, imageSrc = '', imageFocus, + imageAspectRatio = '3x4', tabColor, + isHorizontal, linkText, link, animation = 'none', @@ -51,6 +56,8 @@ export const InitiativeCard = ({ let cardIcon: IconType; let iconAnimation: IconAnimationType; + const imageSize = imageAspectRatio === '3x4' ? '510x680' : '700x700'; + switch (link?.linktype) { case 'asset': cardIcon = 'download'; @@ -69,33 +76,33 @@ export const InitiativeCard = ({ -
-
+
+
{heading}
-
+
{body} + {/* Only show the button styled CTA for XL breakpoint and up */} + {isHorizontal && linkText && ( + + {linkText} + + )}
cnb('max-w-prose mx-auto rs-mt-3 *:*:text-center text-balance mb-0', isDarktheme && 'text-shadow-sm'); +export const body = (isDarktheme: boolean) => cnb('max-w-prose mx-auto rs-mt-3 *:*:text-center *:*:leading-snug text-balance mb-0', isDarktheme && 'text-shadow-sm'); export const cta = (isStackedCtas: boolean) => cnb( 'gap-27 mx-auto w-fit *:mx-auto rs-mt-4', !isStackedCtas && 'md:flex-row', diff --git a/components/Storyblok/SbInitiativeCard.tsx b/components/Storyblok/SbInitiativeCard.tsx index 54cb5baa..6ed5bc38 100644 --- a/components/Storyblok/SbInitiativeCard.tsx +++ b/components/Storyblok/SbInitiativeCard.tsx @@ -1,6 +1,6 @@ import { storyblokEditable } from '@storyblok/react/rsc'; import { type AnimationType } from '../Animate'; -import { InitiativeCard } from '../InitiativeCard'; +import { InitiativeCard, type InitiativeCardImageAspectRatio } from '../InitiativeCard'; import { type HeadingType } from '../Typography'; import { type SbImageType, type SbLinkType } from './Storyblok.types'; import { paletteAccentColors, type PaletteAccentHexColorType } from '@/utilities/colorPalettePlugin'; @@ -12,6 +12,8 @@ type SbInitiativeCardProps = { headingLevel?: HeadingType; body?: string; image?: SbImageType; + imageAspectRatio?: InitiativeCardImageAspectRatio; + isHorizontal?: boolean; tabColor?: { value?: PaletteAccentHexColorType; } @@ -28,7 +30,9 @@ export const SbInitiativeCard = ({ headingLevel, body, image: { filename, focus } = {}, + imageAspectRatio, tabColor: { value } = {}, + isHorizontal, linkText, link, animation, @@ -43,6 +47,8 @@ export const SbInitiativeCard = ({ body={body} imageSrc={filename} imageFocus={focus} + imageAspectRatio={imageAspectRatio} + isHorizontal={isHorizontal} tabColor={paletteAccentColors[value]} linkText={linkText} link={link} diff --git a/components/Storyblok/SbSection/SbSection.tsx b/components/Storyblok/SbSection/SbSection.tsx index 2e677445..3538e6dd 100644 --- a/components/Storyblok/SbSection/SbSection.tsx +++ b/components/Storyblok/SbSection/SbSection.tsx @@ -236,7 +236,7 @@ export const SbSection = ({ font={isSerifHeader ? 'serif' : 'sans'} weight={isSerifHeader ? 'semibold' : 'normal'} align={headerAlign} - color={bgColor === 'black' ? 'black-20' : 'black-90'} + color={bgColor === 'black' ? 'black-20' : 'black'} noMargin className={styles.subhead(headerAlign)} >