From 2633742127c86a5d892f80f6f911cc2c031e3645 Mon Sep 17 00:00:00 2001 From: Hsu Zhong Jun <27919917+dcshzj@users.noreply.github.com> Date: Tue, 26 Sep 2023 16:21:33 +0800 Subject: [PATCH 01/11] feat(announcements): add help overlay (#1521) --- src/layouts/EditHomepage/EditHomepage.jsx | 25 +++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/layouts/EditHomepage/EditHomepage.jsx b/src/layouts/EditHomepage/EditHomepage.jsx index 4c780ff44..0617027f6 100644 --- a/src/layouts/EditHomepage/EditHomepage.jsx +++ b/src/layouts/EditHomepage/EditHomepage.jsx @@ -41,7 +41,10 @@ import { validateAnnouncementItems, } from "utils/validators" -import { HomepageStartEditingImage } from "assets" +import { + HomepageStartEditingImage, + HomepageAnnouncementsSampleImage, +} from "assets" import { EditorHomepageFrontmatterSection } from "types/homepage" import { DEFAULT_RETRY_MSG } from "utils" @@ -1316,21 +1319,27 @@ const EditHomepage = ({ match }) => { subtitle={INFOBAR_SECTION.subtitle} onClick={() => onClick(INFOBAR_SECTION.id)} /> - {/* NOTE: Check if the sections contain any `announcements` + {/* NOTE: Check if the sections contain any `announcements` and if it does, prevent creation of another `resources` section */} {showNewLayouts && !frontMatter.sections.some( ({ announcements }) => !!announcements ) && ( - onClick(ANNOUNCEMENT_BLOCK.id)} - /> + } + > + onClick(ANNOUNCEMENT_BLOCK.id)} + /> + )} - {/* NOTE: Check if the sections contain any `resources` + {/* NOTE: Check if the sections contain any `resources` and if it does, prevent creation of another `resources` section */} {!frontMatter.sections.some( From 5be3e28bb934a58e20a50ead76a44c0049530cb4 Mon Sep 17 00:00:00 2001 From: seaerchin <44049504+seaerchin@users.noreply.github.com> Date: Wed, 27 Sep 2023 02:14:36 +0800 Subject: [PATCH 02/11] refactor(styles): shift to theme (#1523) Co-authored-by: seaerchin --- .../isomer-template/components/_index.scss | 1 + .../homepage/_announcements.scss} | 0 .../components/homepage/_hero.scss | 17 +++ .../components/homepage/_index.scss | 2 + src/styles/isomer-template/styles.scss | 15 +-- .../isomer-template/theme/_breakpoints.scss | 9 ++ src/styles/isomer-template/theme/_colors.scss | 9 ++ src/styles/isomer-template/theme/_index.scss | 5 + src/styles/isomer-template/theme/_layout.scss | 3 + .../{helpers.scss => theme/_spacing.scss} | 1 + .../isomer-template/theme/_text-styles.scss | 125 ++++++++++++++++++ 11 files changed, 174 insertions(+), 13 deletions(-) create mode 100644 src/styles/isomer-template/components/_index.scss rename src/styles/isomer-template/{homepage/announcements.scss => components/homepage/_announcements.scss} (100%) create mode 100644 src/styles/isomer-template/components/homepage/_hero.scss create mode 100644 src/styles/isomer-template/components/homepage/_index.scss create mode 100644 src/styles/isomer-template/theme/_breakpoints.scss create mode 100644 src/styles/isomer-template/theme/_colors.scss create mode 100644 src/styles/isomer-template/theme/_index.scss create mode 100644 src/styles/isomer-template/theme/_layout.scss rename src/styles/isomer-template/{helpers.scss => theme/_spacing.scss} (99%) create mode 100644 src/styles/isomer-template/theme/_text-styles.scss diff --git a/src/styles/isomer-template/components/_index.scss b/src/styles/isomer-template/components/_index.scss new file mode 100644 index 000000000..f7c060ff5 --- /dev/null +++ b/src/styles/isomer-template/components/_index.scss @@ -0,0 +1 @@ +@import "./homepage"; diff --git a/src/styles/isomer-template/homepage/announcements.scss b/src/styles/isomer-template/components/homepage/_announcements.scss similarity index 100% rename from src/styles/isomer-template/homepage/announcements.scss rename to src/styles/isomer-template/components/homepage/_announcements.scss diff --git a/src/styles/isomer-template/components/homepage/_hero.scss b/src/styles/isomer-template/components/homepage/_hero.scss new file mode 100644 index 000000000..7ae3cf01b --- /dev/null +++ b/src/styles/isomer-template/components/homepage/_hero.scss @@ -0,0 +1,17 @@ +.min-height-mobile { + min-height: 398px; +} + +.gray-overlay { + background: rgba(0, 0, 0, 0.25); +} + +.hero-body-padding { + padding: 3rem 1.5rem; +} + +@media screen and (min-width: 1024px) { + .hero-floating { + padding: 3rem; + } +} diff --git a/src/styles/isomer-template/components/homepage/_index.scss b/src/styles/isomer-template/components/homepage/_index.scss new file mode 100644 index 000000000..8abc493e9 --- /dev/null +++ b/src/styles/isomer-template/components/homepage/_index.scss @@ -0,0 +1,2 @@ +@import "./announcements.scss"; +@import "./hero.scss"; diff --git a/src/styles/isomer-template/styles.scss b/src/styles/isomer-template/styles.scss index 801cb90c8..7986c6af6 100644 --- a/src/styles/isomer-template/styles.scss +++ b/src/styles/isomer-template/styles.scss @@ -1,13 +1,2 @@ -// Minimum width before a media query is triggered -$breakpoints: ( - "": 0px, - sm: 431px, - md: 770px, - lg: 1024px, - xl: 1280px, - xxl: 1408px, -); - -@import "helpers"; - -@import "homepage/announcements"; +@import "theme"; +@import "components"; diff --git a/src/styles/isomer-template/theme/_breakpoints.scss b/src/styles/isomer-template/theme/_breakpoints.scss new file mode 100644 index 000000000..4af304aba --- /dev/null +++ b/src/styles/isomer-template/theme/_breakpoints.scss @@ -0,0 +1,9 @@ +// Minimum width before a media query is triggered +$breakpoints: ( + "": 0px, + sm: 431px, + md: 770px, + lg: 1024px, + xl: 1280px, + xxl: 1408px, +); diff --git a/src/styles/isomer-template/theme/_colors.scss b/src/styles/isomer-template/theme/_colors.scss new file mode 100644 index 000000000..59b281fe3 --- /dev/null +++ b/src/styles/isomer-template/theme/_colors.scss @@ -0,0 +1,9 @@ +$canvas-base: #ffffff; +$content-base: #000000; +$utility-theme-color: var(--site-primary-color); +$canvas-inverse: #000000; +$content-inverse: #ffffff; +$utility-secondary-color: var(--site-secondary-color); +$canvas-translucent-grey: #00000080; +$interaction-hover: #f9f9f9; +$stroke-default: #d0d5dd; diff --git a/src/styles/isomer-template/theme/_index.scss b/src/styles/isomer-template/theme/_index.scss new file mode 100644 index 000000000..d44e97fc2 --- /dev/null +++ b/src/styles/isomer-template/theme/_index.scss @@ -0,0 +1,5 @@ +@import "_breakpoints.scss"; +@import "_layout.scss"; +@import "_spacing.scss"; +@import "_colors.scss"; +@import "_text-styles.scss"; diff --git a/src/styles/isomer-template/theme/_layout.scss b/src/styles/isomer-template/theme/_layout.scss new file mode 100644 index 000000000..b33ef8217 --- /dev/null +++ b/src/styles/isomer-template/theme/_layout.scss @@ -0,0 +1,3 @@ +.flex-end { + justify-content: flex-end; +} diff --git a/src/styles/isomer-template/helpers.scss b/src/styles/isomer-template/theme/_spacing.scss similarity index 99% rename from src/styles/isomer-template/helpers.scss rename to src/styles/isomer-template/theme/_spacing.scss index d8614c0c6..fe8b6fe2b 100644 --- a/src/styles/isomer-template/helpers.scss +++ b/src/styles/isomer-template/theme/_spacing.scss @@ -40,6 +40,7 @@ $spaceamounts: ( 80, 96 ); + $sides: ( "t": "top", "b": "bottom", diff --git a/src/styles/isomer-template/theme/_text-styles.scss b/src/styles/isomer-template/theme/_text-styles.scss new file mode 100644 index 000000000..fe3402914 --- /dev/null +++ b/src/styles/isomer-template/theme/_text-styles.scss @@ -0,0 +1,125 @@ +.h1 { + color: $content-base; + + font-family: Lato; + font-size: 3rem; + font-style: normal; + font-weight: 700; + line-height: 3.5rem; /* 116.667% */ + letter-spacing: -1.056px; +} + +.h2 { + color: $content-base; + + font-family: Lato; + font-size: 2rem; + font-style: normal; + font-weight: 700; + line-height: 2.5rem; /* 125% */ + letter-spacing: -0.044rem; +} + +.h3 { + color: $content-base; + + font-feature-settings: "clig" off, "liga" off; + font-family: Lato; + font-size: 1.625rem; + font-style: normal; + font-weight: 700; + line-height: 2rem; /* 123.077% */ +} + +.subtitle-1 { + color: $content-base; + + /* new-subtitle-1 */ + font-family: Lato; + font-size: 1.125rem; + font-style: normal; + font-weight: 400; + line-height: 1.75rem; /* 155.556% */ + letter-spacing: -0.02475rem; +} + +.subtitle-2 { + color: $content-base; + + /* new-subtitle-2 */ + font-family: Lato; + font-size: 1rem; + font-style: normal; + font-weight: 400; + line-height: 1.375rem; + letter-spacing: 0.09375rem; + text-transform: uppercase; +} + +.body-1 { + color: $content-base; + font-variant-numeric: lining-nums tabular-nums; + font-feature-settings: "clig" off, "liga" off; + + /* new-body-1 */ + font-family: Lato; + font-size: 1.25rem; + font-style: normal; + font-weight: 400; + line-height: 2rem; /* 160% */ +} + +.body-2 { + color: $content-base; + + font-feature-settings: "clig" off, "liga" off; + font-family: Lato; + font-size: 1.125rem; + font-style: normal; + font-weight: 400; + line-height: 1.75rem; /* 160% */ +} + +.link-button { + color: $utility-theme-color; + text-align: center; + font-feature-settings: "clig" off, "liga" off; + + /* new-linkbutton */ + font-family: Lato; + font-size: 1.125rem; + font-style: normal; + font-weight: 600; + line-height: 2rem; /* 177.778% */ + text-decoration-line: underline; + text-transform: uppercase; +} + +.button-text { + color: $utility-theme-color; + text-align: center; + font-feature-settings: "clig" off, "liga" off; + + /* new-buttontext */ + font-family: Lato; + font-size: 1rem; + font-style: normal; + font-weight: 600; + line-height: 2rem; /* 200% */ + text-transform: uppercase; +} + +.link { + color: $utility-theme-color; + font-variant-numeric: lining-nums tabular-nums; + font-feature-settings: "clig" off, "liga" off; + + /* new-link */ + font-family: Lato; + font-size: 1.125rem; + font-style: normal; + font-weight: 600; + line-height: 1.5rem; /* 133.333% */ + letter-spacing: 0.01688rem; + text-decoration-line: underline; +} From 83cd5750369b88fabbe8937eb2c72fdb16edd96a Mon Sep 17 00:00:00 2001 From: seaerchin <44049504+seaerchin@users.noreply.github.com> Date: Wed, 27 Sep 2023 02:16:04 +0800 Subject: [PATCH 03/11] refactor(hero): chnage to use breakpoints (#1524) Co-authored-by: seaerchin --- .../homepage/HeroSection/HeroSideLayout.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/templates/homepage/HeroSection/HeroSideLayout.tsx b/src/templates/homepage/HeroSection/HeroSideLayout.tsx index a493f6973..b2ce16019 100644 --- a/src/templates/homepage/HeroSection/HeroSideLayout.tsx +++ b/src/templates/homepage/HeroSection/HeroSideLayout.tsx @@ -39,16 +39,16 @@ const HeroInfoboxDesktop = ({ }: HeroInfoboxDesktopProps) => { return (
-
-
-

+
+
+

{title && ( <> @@ -172,7 +172,7 @@ export const HeroSideLayout = ({ >
-
-

+
+

{title} From fe243e955825562f086b3e6a26bb7194213c516f Mon Sep 17 00:00:00 2001 From: Kishore <42832651+kishore03109@users.noreply.github.com> Date: Wed, 27 Sep 2023 09:17:38 +0800 Subject: [PATCH 04/11] feat(feature tour): FF for hero (#1508) * fix(homepagepreview): add default if no variant * build(inView): allows us to know if elem is in view * chore(heroBannerToolTipImage): add in required image * feat(hero feature tour): add in storybook for feature tour * feat(hero): add in functionality within hero body * fix(feature tour homepage): no need beacon * fix(homepage preview): unintended rebase commit * fix(feature tour): fix rebase issues * fix(hero-body): fix bugs from rebase * fix(feature tour): styling fixes) * fix(feature tour): fix feature tour render when component is loading * fix(feature tour): fix tip badge being shown * fix(edithomepage): fix padding issue * fix(featureTour): attempt ui bug w useEffect * fix(hero body): add deps --------- Co-authored-by: seaerchin --- package-lock.json | 9 ++ package.json | 1 + src/assets/images/HeroBannerToolTipImage.tsx | 36 ++++++++ src/assets/images/index.ts | 1 + src/constants/localStorage.ts | 1 + .../FeatureTour/FeatureTourContent.tsx | 29 +++++++ .../FeatureTour/FeatureTourSequence.ts | 16 ++++ .../FeatureTourTooltip.stories.tsx | 32 +++++-- .../FeatureTour/FeatureTourTooltip.tsx | 81 ++++++++++++------ src/layouts/components/Homepage/HeroBody.tsx | 85 +++++++++++++------ 10 files changed, 228 insertions(+), 63 deletions(-) create mode 100644 src/assets/images/HeroBannerToolTipImage.tsx create mode 100644 src/features/FeatureTour/FeatureTourContent.tsx diff --git a/package-lock.json b/package-lock.json index 702859c13..ccd8536a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -62,6 +62,7 @@ "react-hook-form": "^7.32.0", "react-icons": "^4.4.0", "react-input-mask": "^2.0.4", + "react-intersection-observer": "^9.5.2", "react-joyride": "^2.5.3", "react-markdown": "^8.0.7", "react-query": "^3.34.16", @@ -30758,6 +30759,14 @@ "react": "^16.8.4 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-intersection-observer": { + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.5.2.tgz", + "integrity": "sha512-EmoV66/yvksJcGa1rdW0nDNc4I1RifDWkT50gXSFnPLYQ4xUptuDD4V7k+Rj1OgVAlww628KLGcxPXFlOkkU/Q==", + "peerDependencies": { + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-is": { "version": "17.0.2", "license": "MIT" diff --git a/package.json b/package.json index bfa85cbba..220bdd96d 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "react-hook-form": "^7.32.0", "react-icons": "^4.4.0", "react-input-mask": "^2.0.4", + "react-intersection-observer": "^9.5.2", "react-joyride": "^2.5.3", "react-markdown": "^8.0.7", "react-query": "^3.34.16", diff --git a/src/assets/images/HeroBannerToolTipImage.tsx b/src/assets/images/HeroBannerToolTipImage.tsx new file mode 100644 index 000000000..2032ebe9f --- /dev/null +++ b/src/assets/images/HeroBannerToolTipImage.tsx @@ -0,0 +1,36 @@ +export const HeroBannerToolTipImage = ( + props: React.SVGProps +): JSX.Element => { + return ( + + + + + + + + + + ) +} diff --git a/src/assets/images/index.ts b/src/assets/images/index.ts index 00aa40dce..cecd9ea7b 100644 --- a/src/assets/images/index.ts +++ b/src/assets/images/index.ts @@ -19,3 +19,4 @@ export * from "./SiteLaunchPendingImage" export * from "./NotFoundSubmarineImage" export * from "./HomepageAnnouncementsSampleImage" export * from "./HomepageTextCardsSampleImage" +export * from "./HeroBannerToolTipImage" diff --git a/src/constants/localStorage.ts b/src/constants/localStorage.ts index 3a099f12a..41db10956 100644 --- a/src/constants/localStorage.ts +++ b/src/constants/localStorage.ts @@ -5,4 +5,5 @@ export enum LOCAL_STORAGE_KEYS { DashboardFeatureTour = "dashboard-identity-feature-tour-v1", WorkspaceFeatureTour = "workspace-identity-feature-tour-v1", Feedback = "feedback", + HeroOptionsFeatureTour = "hero-options-feature-tour-v1", } diff --git a/src/features/FeatureTour/FeatureTourContent.tsx b/src/features/FeatureTour/FeatureTourContent.tsx new file mode 100644 index 000000000..771f06c65 --- /dev/null +++ b/src/features/FeatureTour/FeatureTourContent.tsx @@ -0,0 +1,29 @@ +import { Icon, Text } from "@chakra-ui/react" +import { Badge } from "@opengovsg/design-system-react" +import { BiCheck } from "react-icons/bi" + +export const HeroOptionsFeatureTourContent = (): JSX.Element => { + return ( + <> + + + New feature + + + {" "} + Now you can customise your hero banner with various layouts!{" "} + + + {`We've added some variations to how you can display your hero section. + Try them out here.`} + + + ) +} diff --git a/src/features/FeatureTour/FeatureTourSequence.ts b/src/features/FeatureTour/FeatureTourSequence.ts index c2a43e37f..91ddb3d7d 100644 --- a/src/features/FeatureTour/FeatureTourSequence.ts +++ b/src/features/FeatureTour/FeatureTourSequence.ts @@ -1,5 +1,10 @@ +import React from "react" import { Step } from "react-joyride" +import { HeroBannerToolTipImage } from "assets/images" + +import { HeroOptionsFeatureTourContent } from "./FeatureTourContent" + export const DASHBOARD_FEATURE_STEPS: Array = [ { target: "#isomer-dashboard-feature-tour-step-1", @@ -62,3 +67,14 @@ export const STORYBOOK_FEATURE_STEPS: Array = [ placement: "top-end", }, ] + +export const HERO_OPTIONS_FEATURE_STEPS: Array = [ + { + target: "#isomer-hero-feature-tour-step-1", + content: React.createElement("div", {}, HeroOptionsFeatureTourContent()), + floaterProps: { placement: "right-end" }, + placement: "right-end", + title: React.createElement("div", {}, HeroBannerToolTipImage({})), + disableBeacon: true, + }, +] diff --git a/src/features/FeatureTour/FeatureTourTooltip.stories.tsx b/src/features/FeatureTour/FeatureTourTooltip.stories.tsx index f1429ec84..d0dc35798 100644 --- a/src/features/FeatureTour/FeatureTourTooltip.stories.tsx +++ b/src/features/FeatureTour/FeatureTourTooltip.stories.tsx @@ -1,9 +1,13 @@ import { ButtonProps } from "@opengovsg/design-system-react" -import { Meta, Story } from "@storybook/react" +import { Meta, StoryFn } from "@storybook/react" import { useState } from "react" +import { Step } from "react-joyride" import { FeatureTourContext } from "./FeatureTourContext" -import { DASHBOARD_FEATURE_STEPS } from "./FeatureTourSequence" +import { + DASHBOARD_FEATURE_STEPS, + HERO_OPTIONS_FEATURE_STEPS, +} from "./FeatureTourSequence" import { FeatureTourStep, FeatureTourTooltip, @@ -18,26 +22,27 @@ export default { }, } as Meta -const Template: Story = (args) => { - const { index, isLastStep } = args +const Template: StoryFn = ( + args +) => { + const { index, isLastStep, steps = DASHBOARD_FEATURE_STEPS } = args const [featureStep, setFeatureStep] = useState(index ?? 0) const handleNextClick = () => { - featureStep === DASHBOARD_FEATURE_STEPS.length - 1 + featureStep === steps.length - 1 ? setFeatureStep(featureStep) : setFeatureStep(featureStep + 1) } const getFeatureTourTooltipContent = (step: number): FeatureTourStep => { return { - title: DASHBOARD_FEATURE_STEPS[step].title, - content: DASHBOARD_FEATURE_STEPS[step].content, + title: steps[step].title, + content: steps[step].content, } } const featureTourTooltipContent = getFeatureTourTooltipContent(featureStep) - const isThisLastStep = - isLastStep ?? featureStep === DASHBOARD_FEATURE_STEPS.length - 1 + const isThisLastStep = isLastStep ?? featureStep === steps.length - 1 const mockPrimaryProps: ButtonProps = { onClick: handleNextClick, } @@ -53,6 +58,7 @@ const Template: Story = (args) => { primaryProps={mockPrimaryProps} isLastStep={isThisLastStep} index={featureStep} + size={steps.length} /> ) @@ -65,3 +71,11 @@ LastFeatureStep.args = { index: DASHBOARD_FEATURE_STEPS.length - 1, isLastStep: true, } + +export const HeroBannerStep = Template.bind({}) + +HeroBannerStep.args = { + index: 0, + isLastStep: true, + steps: HERO_OPTIONS_FEATURE_STEPS, +} diff --git a/src/features/FeatureTour/FeatureTourTooltip.tsx b/src/features/FeatureTour/FeatureTourTooltip.tsx index de99e8a42..ed4d62015 100644 --- a/src/features/FeatureTour/FeatureTourTooltip.tsx +++ b/src/features/FeatureTour/FeatureTourTooltip.tsx @@ -5,7 +5,6 @@ import { BiBulb, BiRightArrowAlt } from "react-icons/bi" import { ProgressIndicator } from "components/ProgressIndicator/ProgressIndicator" import { useFeatureTourContext } from "./FeatureTourContext" -import { DASHBOARD_FEATURE_STEPS } from "./FeatureTourSequence" export interface FeatureTourStep { content: React.ReactNode @@ -32,50 +31,78 @@ export const FeatureTourTooltip = ({ index, }: FeatureTourTooltipProps): JSX.Element => { const { paginationCallback } = useFeatureTourContext() + const showProgressIndicator = size > 1 + + let isTipBadgeShown = true + let titleComponent: React.ReactNode + if (typeof step.title === "string") { + titleComponent = ( + + {step.title} + + ) + } else { + titleComponent = step.title + isTipBadgeShown = false + } + + let contentComponent: React.ReactNode + if (typeof step.content === "string") { + contentComponent = ( + + {step.content} + + ) + } else { + contentComponent = step.content + } + return ( - - - - Tip - - - - {step.title} - - - {step.content} - + {isTipBadgeShown && ( + + + + Tip + + + )} + + {titleComponent} + {contentComponent} + - + {showProgressIndicator && ( + + )} {isLastStep ? ( ) : ( + {link && ( + + See release notes + + )} + + ) : ( + + + ))} + + + + + + + + + + ) +} diff --git a/src/styles/isomer-template/components/homepage/_index.scss b/src/styles/isomer-template/components/homepage/_index.scss index 8abc493e9..5d3e63632 100644 --- a/src/styles/isomer-template/components/homepage/_index.scss +++ b/src/styles/isomer-template/components/homepage/_index.scss @@ -1,2 +1,3 @@ @import "./announcements.scss"; @import "./hero.scss"; +@import "./text-cards.scss"; diff --git a/src/styles/isomer-template/components/homepage/_text-cards.scss b/src/styles/isomer-template/components/homepage/_text-cards.scss new file mode 100644 index 000000000..c2c931ba8 --- /dev/null +++ b/src/styles/isomer-template/components/homepage/_text-cards.scss @@ -0,0 +1,62 @@ +.textcards-section { + flex-direction: column; + align-items: center; + text-align: center; + + @media screen and (min-width: 1408px) { + max-width: 1440px; + margin: auto; + } +} + +.textcards-card-section { + justify-content: center; + align-items: flex-start; + gap: 2rem; + width: 100%; + flex-wrap: wrap; + flex-direction: column; + + @media screen and (min-width: 770px) { + flex-direction: row; + } + + .textcards-card-body { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 1rem; + flex: 1 0 0; + align-self: stretch; + color: #484848; + + border-radius: 4px; + border: 1px solid $stroke-default; + background: var(--white, #FFF); + box-shadow: 0px 0px 10px 0px rgba(191, 191, 191, 0.50); + + @media screen and (min-width: 770px) { + max-width: 50%; + } + + @media screen and (min-width: 1280px) { + max-width: 40%; + } + + @media screen and (min-width: 770px) and (max-width: 1279px) { + flex: 0 0 calc(50% - 24px); + } + + &:hover { + background-color: $interaction-hover; + cursor: pointer; + > .link { + color: var(--site-secondary-color-hover); + } + } + + .textcards-card-description { + flex-grow: 1; + } + } +} \ No newline at end of file diff --git a/src/styles/isomer-template/shared.scss b/src/styles/isomer-template/shared.scss new file mode 100644 index 000000000..a6a82c118 --- /dev/null +++ b/src/styles/isomer-template/shared.scss @@ -0,0 +1,4 @@ +@charset 'UTF-8'; + +$stroke-default-color: #D0D5DD; +$interaction-hover-color: #F9F9F9; \ No newline at end of file diff --git a/src/styles/isomer-template/theme/_text-styles.scss b/src/styles/isomer-template/theme/_text-styles.scss index fe3402914..c4b620e16 100644 --- a/src/styles/isomer-template/theme/_text-styles.scss +++ b/src/styles/isomer-template/theme/_text-styles.scss @@ -1,3 +1,14 @@ +display-1 { + color: $content-base; + + font-family: Lato; + font-size: 4rem; + font-style: normal; + font-weight: 700; + line-height: 5rem; /* 125% */ + letter-spacing: -1.408px; +} + .h1 { color: $content-base; @@ -9,6 +20,17 @@ letter-spacing: -1.056px; } +.h1-small { + color: $content-base; + + font-family: Lato; + font-size: 2.75rem; + font-style: normal; + font-weight: 700; + line-height: 3.5rem; /* 116.667% */ + letter-spacing: -1.056px; +} + .h2 { color: $content-base; @@ -96,7 +118,7 @@ } .button-text { - color: $utility-theme-color; + color: var(--site-secondary-color); text-align: center; font-feature-settings: "clig" off, "liga" off; @@ -110,7 +132,7 @@ } .link { - color: $utility-theme-color; + color: var(--site-secondary-color); font-variant-numeric: lining-nums tabular-nums; font-feature-settings: "clig" off, "liga" off; @@ -122,4 +144,8 @@ line-height: 1.5rem; /* 133.333% */ letter-spacing: 0.01688rem; text-decoration-line: underline; + + &:hover { + color: var(--site-secondary-color-hover) + } } diff --git a/src/templates/homepage/TextCardsSection.tsx b/src/templates/homepage/TextCardsSection.tsx new file mode 100644 index 000000000..c2b198f77 --- /dev/null +++ b/src/templates/homepage/TextCardsSection.tsx @@ -0,0 +1,97 @@ +import { ForwardedRef, forwardRef, RefObject } from "react" + +import editorStyles from "styles/isomer-cms/pages/Editor.module.scss" + +import { getClassNames } from "templates/utils/stylingUtils" + +import { TextcardsSection } from "types/homepage" + +interface TemplateTextCardsSectionProps extends TextcardsSection { + sectionIndex: number +} + +const TemplateTextCardsSection = forwardRef< + HTMLDivElement, + TemplateTextCardsSectionProps +>( + ( + { + title, + subtitle, + description, + cards, + sectionIndex, + }: TemplateTextCardsSectionProps, + ref: ForwardedRef + ) => { + return ( +
+
+

+ {subtitle} +

+

+ {title} +

+

+ {description} +

+
+ {!!cards && + cards.map((card) => ( + <> + +

{card.title}

+

+ {card.description} +

+

{card.linktext}

+
+ + ))} +
+
+
+ ) + } +) + +export default TemplateTextCardsSection diff --git a/src/types/homepage.ts b/src/types/homepage.ts index 52797c15f..00db698b3 100644 --- a/src/types/homepage.ts +++ b/src/types/homepage.ts @@ -78,6 +78,19 @@ export interface AnnouncementsBlockSection { subtitle?: string announcement_items: AnnouncementOption[] } +export interface TextCardItem { + title: string + description?: string + linktext: string + url: string +} + +export interface TextcardsSection { + title: string + subtitle?: string + description?: string + cards: TextCardItem[] +} export interface HomepageDto { content: { @@ -94,6 +107,7 @@ export interface HomepageDto { | InfopicSection | ResourcesSection | AnnouncementsBlockSection + | TextcardsSection )[] } pageBody?: string @@ -106,6 +120,7 @@ export type EditorHomepageElement = | "dropdownelem" | "highlight" | "announcement" + | `textCardItem-${number}` export type PossibleEditorSections = IterableElement< | EditorHomepageState["frontMatter"]["sections"] | EditorHeroDropdownSection["dropdown"]["options"] @@ -136,12 +151,27 @@ export type AnnouncementsFrontmatterSection = { announcements: AnnouncementsBlockSection } +export interface EditortextCardItemsSection { + cards: [] +} + +export interface EditorTextcardSection extends EditortextCardItemsSection { + title: string + subtitle: string + description: string +} + +export type TextcardFrontmatterSection = { + textcards: EditorTextcardSection +} + export type EditorHomepageFrontmatterSection = | HeroFrontmatterSection | ResourcesFrontmatterSection | InfopicFrontmatterSection | InfobarFrontmatterSection | AnnouncementsFrontmatterSection + | TextcardFrontmatterSection export const EditorHomepageFrontmatterSection = { isHero: ( @@ -164,6 +194,10 @@ export const EditorHomepageFrontmatterSection = { section: EditorHomepageFrontmatterSection ): section is AnnouncementsFrontmatterSection => !!(section as AnnouncementsFrontmatterSection).announcements, + isTextcard: ( + section: EditorHomepageFrontmatterSection + ): section is TextcardFrontmatterSection => + !!(section as TextcardFrontmatterSection).textcards, } export interface EditorHomepageState { @@ -175,6 +209,7 @@ export interface EditorHomepageState { dropdownElems: unknown[] highlights: unknown[] announcementItems: unknown[] + textcards: unknown[][] } displaySections: unknown[] displayDropdownElems: unknown[] diff --git a/src/utils/validators.js b/src/utils/validators.js index 43c79398b..4856af436 100644 --- a/src/utils/validators.js +++ b/src/utils/validators.js @@ -124,6 +124,18 @@ const ANNOUNCEMENT_TITLE_MAX_LENGTH = 100 const ANNOUNCEMENT_DESCRIPTION_MIN_LENGTH = 0 const ANNOUNCEMENT_DESCRIPTION_MAX_LENGTH = 300 const ANNOUNCEMENT_LINK_TEXT_URL_MAX_LENGTH = 50 +// Text cards +const TEXTCARDS_BLOCK_TITLE_MIN_LENGTH = 0 +const TEXTCARDS_BLOCK_TITLE_MAX_LENGTH = 50 +const TEXTCARDS_BLOCK_SUBTITLE_MAX_LENGTH = 30 +const TEXTCARDS_BLOCK_DESCRIPTION_MAX_LENGTH = 200 + +const TEXTCARDS_CARD_TITLE_MIN_LENGTH = 0 +const TEXTCARDS_CARD_TITLE_MAX_LENGTH = 50 +const TEXTCARDS_CARD_DESCRIPTION_MAX_LENGTH = 80 +const TEXTCARDS_CARD_LINKTEXT_MIN_LENGTH = 0 +const TEXTCARDS_CARD_LINKTEXT_MAX_LENGTH = 50 +const TEXTCARDS_CARD_URL_MIN_LENGTH = 0 // Contact Us Editor // =============== @@ -597,6 +609,89 @@ const validateAnnouncementsSection = ( return newSectionError } +const validateTextcardsSection = (sectionError, sectionType, field, value) => { + const newSectionError = sectionError + let errorMessage = "" + switch (field) { + case "title": { + // Title is too short + if (value.length <= TEXTCARDS_CARD_TITLE_MIN_LENGTH) { + errorMessage = `Title should be longer than ${TEXTCARDS_BLOCK_TITLE_MIN_LENGTH} characters.` + } + // Title is too long + if (value.length >= TEXTCARDS_CARD_TITLE_MAX_LENGTH) { + errorMessage = `Title should be shorter than ${TEXTCARDS_BLOCK_TITLE_MAX_LENGTH} characters.` + } + break + } + case "subtitle": { + // Subtitle is too long + if (value.length >= TEXTCARDS_BLOCK_SUBTITLE_MAX_LENGTH) { + errorMessage = `Subtitle should be shorter than ${TEXTCARDS_BLOCK_SUBTITLE_MAX_LENGTH} characters.` + } + break + } + case "description": { + // Button text is too long + if (value.length >= TEXTCARDS_BLOCK_DESCRIPTION_MAX_LENGTH) { + errorMessage = `Button text should be shorter than ${TEXTCARDS_BLOCK_DESCRIPTION_MAX_LENGTH} characters.` + } + break + } + default: + break + } + newSectionError[sectionType][field] = errorMessage + return newSectionError +} + +const validateTextcard = (cardError, field, value) => { + const newHighlightError = cardError + let errorMessage = "" + switch (field) { + case "title": { + // Title is too short + if (value.length <= TEXTCARDS_CARD_TITLE_MIN_LENGTH) { + errorMessage = `The title should be longer than ${TEXTCARDS_CARD_TITLE_MIN_LENGTH} characters.` + } + // Title is too long + if (value.length >= TEXTCARDS_CARD_TITLE_MAX_LENGTH) { + errorMessage = `The title should be shorter than ${TEXTCARDS_CARD_TITLE_MAX_LENGTH} characters.` + } + break + } + case "description": { + // Description is too long + if (value.length >= TEXTCARDS_CARD_DESCRIPTION_MAX_LENGTH) { + errorMessage = `The description should be shorter than ${TEXTCARDS_CARD_DESCRIPTION_MAX_LENGTH} characters.` + } + break + } + case "linktext": { + // Link text is too short + if (value.length <= TEXTCARDS_CARD_LINKTEXT_MIN_LENGTH) { + errorMessage = `The description should be longer than ${TEXTCARDS_CARD_LINKTEXT_MIN_LENGTH} characters.` + } + // Link text is too long + if (value.length >= TEXTCARDS_CARD_LINKTEXT_MAX_LENGTH) { + errorMessage = `The description should be shorter than ${TEXTCARDS_CARD_LINKTEXT_MAX_LENGTH} characters.` + } + break + } + case "url": { + // Url is too short + if (value.length <= TEXTCARDS_CARD_URL_MIN_LENGTH) { + errorMessage = `The description should be longer than ${TEXTCARDS_CARD_URL_MIN_LENGTH} characters.` + } + break + } + default: + break + } + newHighlightError[field] = errorMessage + return newHighlightError +} + const validateSections = (sectionError, sectionType, field, value) => { let newSectionError = sectionError switch (sectionType) { @@ -645,6 +740,15 @@ const validateSections = (sectionError, sectionType, field, value) => { ) break } + case "textcards": { + newSectionError = validateTextcardsSection( + sectionError, + sectionType, + field, + value + ) + break + } default: break } @@ -1071,6 +1175,7 @@ export { validateHighlights, validateAnnouncementItems, validateDropdownElems, + validateTextcard, validateSections, validatePageSettings, validateResourceSettings, From 200fda29a2094e9868c7684b32ffbdb558466e0d Mon Sep 17 00:00:00 2001 From: Kishore <42832651+kishore03109@users.noreply.github.com> Date: Wed, 27 Sep 2023 18:59:23 +0800 Subject: [PATCH 10/11] fix(announemnt): fix announcemnt bug (#1532) --- src/layouts/EditHomepage/EditHomepage.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/layouts/EditHomepage/EditHomepage.jsx b/src/layouts/EditHomepage/EditHomepage.jsx index cd2720ea9..5c189b216 100644 --- a/src/layouts/EditHomepage/EditHomepage.jsx +++ b/src/layouts/EditHomepage/EditHomepage.jsx @@ -846,13 +846,15 @@ const EditHomepage = ({ match }) => { const idArray = id.split("-") const elemType = idArray[0] const index = parseInt(idArray[1], RADIX_PARSE_INT) - if (elemType === "section") { const newScrollRefs = update(scrollRefs, { $splice: [[index, 1]], }) setScrollRefs(newScrollRefs) + if (frontMatter.sections[index].announcements) { + setAnnouncementScrollRefs([]) + } } if (elemType === "announcement") { const newAnnouncementScrollRefs = update(announcementScrollRefs, { From f05e2e9ba8159862b660b6f8c99b74804fa90203 Mon Sep 17 00:00:00 2001 From: Kishore <42832651+kishore03109@users.noreply.github.com> Date: Wed, 27 Sep 2023 21:51:17 +0800 Subject: [PATCH 11/11] 0.46.0 --- CHANGELOG.md | 30 ++++++++++++++++++++---------- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11afc7f70..36cc0350e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,24 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [v0.46.0](https://github.com/isomerpages/isomercms-frontend/compare/v0.45.0...v0.46.0) + +- fix(announemnt): fix announcemnt bug [`#1532`](https://github.com/isomerpages/isomercms-frontend/pull/1532) +- Feat/text cards panel [`#1505`](https://github.com/isomerpages/isomercms-frontend/pull/1505) +- Fix/homepageAnnouncementScroll [`#1530`](https://github.com/isomerpages/isomercms-frontend/pull/1530) +- Feat/homepageAnnouncement [`#1502`](https://github.com/isomerpages/isomercms-frontend/pull/1502) +- fix(image): change image used [`#1531`](https://github.com/isomerpages/isomercms-frontend/pull/1531) +- chore(announcements): sync changes from template [`#1518`](https://github.com/isomerpages/isomercms-frontend/pull/1518) +- feat(feature tour): FF for hero [`#1508`](https://github.com/isomerpages/isomercms-frontend/pull/1508) +- refactor(hero): chnage to use breakpoints [`#1524`](https://github.com/isomerpages/isomercms-frontend/pull/1524) +- refactor(styles): shift to theme [`#1523`](https://github.com/isomerpages/isomercms-frontend/pull/1523) +- feat(announcements): add help overlay [`#1521`](https://github.com/isomerpages/isomercms-frontend/pull/1521) +- release(0.45.0): merge to develop [`#1519`](https://github.com/isomerpages/isomercms-frontend/pull/1519) + #### [v0.45.0](https://github.com/isomerpages/isomercms-frontend/compare/v0.44.0...v0.45.0) +> 25 September 2023 + - Feat/announcement block [`#1497`](https://github.com/isomerpages/isomercms-frontend/pull/1497) - feat: introduce new help overlay for add section button [`#1515`](https://github.com/isomerpages/isomercms-frontend/pull/1515) - feat(template): add ffs as a manual check-in [`#1469`](https://github.com/isomerpages/isomercms-frontend/pull/1469) @@ -38,21 +54,15 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - fix(herobody): solves empty highlight deafult issue [`#1489`](https://github.com/isomerpages/isomercms-frontend/pull/1489) - fix(edithomepage): spread properly [`#1487`](https://github.com/isomerpages/isomercms-frontend/pull/1487) - Release/0.42.0 (develop) [`#1481`](https://github.com/isomerpages/isomercms-frontend/pull/1481) -- fix(editable): hover and focus states for title text [`#1484`](https://github.com/isomerpages/isomercms-frontend/pull/1484) -- Fix/style nits [`#1483`](https://github.com/isomerpages/isomercms-frontend/pull/1483) -- fix: styling [`#1482`](https://github.com/isomerpages/isomercms-frontend/pull/1482) -- fix(editable): change drag handle to be on top part only [`#1475`](https://github.com/isomerpages/isomercms-frontend/pull/1475) -- feat(editable): introduce new nested card variant [`#1478`](https://github.com/isomerpages/isomercms-frontend/pull/1478) -- fix(homepage): various styling fixes [`#1477`](https://github.com/isomerpages/isomercms-frontend/pull/1477) -- Fix/edit nav nits [`#1476`](https://github.com/isomerpages/isomercms-frontend/pull/1476) -- fix(edithomepage): spread properly [`#1474`](https://github.com/isomerpages/isomercms-frontend/pull/1474) -- Chore/fix title text [`#1472`](https://github.com/isomerpages/isomercms-frontend/pull/1472) -- Chore/fix edit nav bar styles [`#1466`](https://github.com/isomerpages/isomercms-frontend/pull/1466) #### [v0.42.0](https://github.com/isomerpages/isomercms-frontend/compare/v0.41.0...v0.42.0) > 7 September 2023 +- fix(editable): hover and focus states for title text [`#1484`](https://github.com/isomerpages/isomercms-frontend/pull/1484) +- Fix/style nits [`#1483`](https://github.com/isomerpages/isomercms-frontend/pull/1483) +- fix: styling [`#1482`](https://github.com/isomerpages/isomercms-frontend/pull/1482) +- fix(editable): change drag handle to be on top part only [`#1475`](https://github.com/isomerpages/isomercms-frontend/pull/1475) - feat(editable): introduce new nested card variant [`#1478`](https://github.com/isomerpages/isomercms-frontend/pull/1478) - fix(homepage): various styling fixes [`#1477`](https://github.com/isomerpages/isomercms-frontend/pull/1477) - Fix/edit nav nits [`#1476`](https://github.com/isomerpages/isomercms-frontend/pull/1476) diff --git a/package-lock.json b/package-lock.json index ccd8536a4..cea216652 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "isomercms-frontend", - "version": "0.45.0", + "version": "0.46.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "isomercms-frontend", - "version": "0.45.0", + "version": "0.46.0", "hasInstallScript": true, "dependencies": { "@braintree/sanitize-url": "^6.0.1", diff --git a/package.json b/package.json index 220bdd96d..bbff11801 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "isomercms-frontend", - "version": "0.45.0", + "version": "0.46.0", "private": true, "engines": { "node": ">=16.0.0"