Skip to content

Commit

Permalink
Merge pull request #4555 from owid/cookie-notice-component
Browse files Browse the repository at this point in the history
🎉 add archieML cookie notice component
  • Loading branch information
ikesau authored Feb 25, 2025
2 parents 4af1906 + 943250b commit 99f4d29
Show file tree
Hide file tree
Showing 21 changed files with 203 additions and 16 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ reindex: itsJustJavascript
node --enable-source-maps itsJustJavascript/baker/algolia/indexPagesToAlgolia.js
@echo '--- Running indexChartsToAlgolia...'
node --enable-source-maps itsJustJavascript/baker/algolia/indexChartsToAlgolia.js
@echo '--- Running indexPostsToAlgolia...'
@echo '--- Running indexExplorerViewsToAlgolia...'
node --enable-source-maps itsJustJavascript/baker/algolia/indexExplorerViewsToAlgolia.js
@echo '--- Running indexExplorerViewsAndChartsToAlgolia...'
node --enable-source-maps itsJustJavascript/baker/algolia/indexExplorerViewsAndChartsToAlgolia.js
Expand Down
1 change: 1 addition & 0 deletions db/model/Gdoc/GdocBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,7 @@ export class GdocBase implements OwidGdocBaseInterface {
"blockquote",
"callout",
"code",
"cookie-notice",
"donors",
"expandable-paragraph",
"entry-summary",
Expand Down
1 change: 1 addition & 0 deletions db/model/Gdoc/enrichedToMarkdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ ${items}
"\n```"
)
})
.with({ type: "cookie-notice" }, () => undefined)
.with({ type: "donors" }, (_): string | undefined =>
markdownComponent("DonorList", {}, exportComponents)
)
Expand Down
8 changes: 8 additions & 0 deletions db/model/Gdoc/enrichedToRaw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import {
RawBlockPerson,
RawBlockNarrativeChart,
RawBlockCode,
RawBlockCookieNotice,
} from "@ourworldindata/types"
import { spanToHtmlString } from "./gdocUtils.js"
import { match, P } from "ts-pattern"
Expand Down Expand Up @@ -148,6 +149,13 @@ export function enrichedBlockToRawBlock(
})),
})
)
.with(
{ type: "cookie-notice" },
(b): RawBlockCookieNotice => ({
type: b.type,
value: {},
})
)
.with(
{ type: "donors" },
(b): RawBlockDonorList => ({
Expand Down
4 changes: 4 additions & 0 deletions db/model/Gdoc/exampleEnrichedBlocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ export const enrichedBlockExamples: Record<
],
parseErrors: [],
},
"cookie-notice": {
type: "cookie-notice",
parseErrors: [],
},
donors: {
type: "donors",
value: {},
Expand Down
1 change: 1 addition & 0 deletions db/model/Gdoc/extractGdocComponentInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ export function enumerateGdocComponentsWithoutChildren(
type: P.union(
"chart-story",
"chart",
"cookie-notice",
"narrative-chart",
"horizontal-rule",
"html",
Expand Down
1 change: 1 addition & 0 deletions db/model/Gdoc/gdocUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ export function extractFilenamesFromBlock(
"chart-story",
"chart",
"code",
"cookie-notice",
"donors",
"entry-summary",
"expandable-paragraph",
Expand Down
9 changes: 9 additions & 0 deletions db/model/Gdoc/rawToArchie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import {
RawBlockPerson,
RawBlockNarrativeChart,
RawBlockCode,
RawBlockCookieNotice,
} from "@ourworldindata/types"
import { isArray } from "@ourworldindata/utils"
import { match } from "ts-pattern"
Expand Down Expand Up @@ -551,6 +552,13 @@ function* rawBlockTopicPageIntroToArchieMLString(
yield "{}"
}

function* rawBlockCookieNoticeToArchieMLString(
_: RawBlockCookieNotice
): Generator<string, void, undefined> {
yield "{.cookie-notice}"
yield "{}"
}

function* rawKeyInsightsToArchieMLString(
block: RawBlockKeyInsights
): Generator<string, void, undefined> {
Expand Down Expand Up @@ -910,6 +918,7 @@ export function* OwidRawGdocBlockToArchieMLStringGenerator(
{ type: "topic-page-intro" },
rawBlockTopicPageIntroToArchieMLString
)
.with({ type: "cookie-notice" }, rawBlockCookieNoticeToArchieMLString)
.with({ type: "key-insights" }, rawKeyInsightsToArchieMLString)
.with(
{ type: "research-and-writing" },
Expand Down
10 changes: 10 additions & 0 deletions db/model/Gdoc/rawToEnriched.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ import {
EnrichedBlockNarrativeChart,
RawBlockCode,
EnrichedBlockCode,
EnrichedBlockCookieNotice,
RawBlockCookieNotice,
} from "@ourworldindata/types"
import {
traverseEnrichedSpan,
Expand Down Expand Up @@ -215,6 +217,7 @@ export function parseRawBlocksToEnrichedBlocks(
.with({ type: "gray-section" }, parseGraySection)
.with({ type: "prominent-link" }, parseProminentLink)
.with({ type: "topic-page-intro" }, parseTopicPageIntro)
.with({ type: "cookie-notice" }, parseCookieNotice)
.with({ type: "key-insights" }, parseKeyInsights)
.with({ type: "research-and-writing" }, parseResearchAndWritingBlock)
.with(
Expand Down Expand Up @@ -1578,6 +1581,13 @@ function parseTopicPageIntro(
}
}

function parseCookieNotice(_: RawBlockCookieNotice): EnrichedBlockCookieNotice {
return {
type: "cookie-notice",
parseErrors: [],
}
}

function parseKeyInsights(raw: RawBlockKeyInsights): EnrichedBlockKeyInsights {
const createError = (error: ParseError): EnrichedBlockKeyInsights => ({
type: "key-insights",
Expand Down
17 changes: 17 additions & 0 deletions packages/@ourworldindata/components/src/Checkbox.scss
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,23 @@
background: white;
}

input:disabled {
+ .custom {
background: $blue-10;
border-color: $blue-20;
color: $blue-50;
}

&:active + .custom {
background: $blue-10;
}

~ .label {
color: $blue-50;
cursor: not-allowed;
}
}

.label {
@include grapher_label-2-regular;
padding-left: $checkbox-size + 8px;
Expand Down
12 changes: 10 additions & 2 deletions packages/@ourworldindata/components/src/Checkbox.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
import * as React from "react"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome/index.js"
import { faCheck } from "@fortawesome/free-solid-svg-icons"
import cx from "classnames"

export class Checkbox extends React.Component<{
checked: boolean
onChange: React.ChangeEventHandler<HTMLInputElement>
label: React.ReactNode
disabled?: boolean
id?: string
"data-test"?: string
}> {
render(): React.ReactElement {
const { checked, onChange, label } = this.props
const { checked, onChange, label, disabled, id } = this.props
const testHook = this.props["data-test"]

return (
<div className="checkbox">
<div className={cx("checkbox", { "checkbox--disabled": disabled })}>
<label>
<input
id={id}
type="checkbox"
data-test={testHook}
checked={checked}
onChange={onChange}
disabled={disabled}
/>
<div className="custom">
{checked && <FontAwesomeIcon icon={faCheck} />}
Expand Down
9 changes: 8 additions & 1 deletion packages/@ourworldindata/components/src/RadioButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,22 @@ export class RadioButton extends React.Component<{
onChange: React.ChangeEventHandler<HTMLInputElement>
label: React.ReactNode
group?: string
disabled?: boolean
id?: string
"data-test"?: string
}> {
render(): React.ReactElement {
const { checked, onChange, label, group } = this.props
const { checked, onChange, label, group, disabled, id } = this.props
const testHook = this.props["data-test"]

return (
<div className="radio">
<label>
<input
type="radio"
id={id}
data-test={testHook}
disabled={disabled}
name={group}
checked={checked}
onChange={onChange}
Expand Down
12 changes: 12 additions & 0 deletions packages/@ourworldindata/components/src/styles/typography.scss
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,18 @@ body {
@include body-3-medium-italic-underlined;
}

@mixin body-3-bold {
font-family: $sans-serif-font-stack;
font-size: 0.875rem;
line-height: 1.5;
font-weight: 700;
letter-spacing: 0.01rem;
}

.body-3-bold {
@include body-3-bold;
}

@mixin label-2-medium {
font-family: $sans-serif-font-stack;
font-size: 0.8125rem;
Expand Down
11 changes: 11 additions & 0 deletions packages/@ourworldindata/types/src/gdocTypes/ArchieMlComponents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,15 @@ export type EnrichedBlockLatestDataInsights = {
type: "latest-data-insights"
} & EnrichedBlockWithParseErrors

export type RawBlockCookieNotice = {
type: "cookie-notice"
value: Record<string, never>
}

export type EnrichedBlockCookieNotice = {
type: "cookie-notice"
} & EnrichedBlockWithParseErrors

export enum SocialLinkType {
X = "x",
Facebook = "facebook",
Expand Down Expand Up @@ -1027,6 +1036,7 @@ export type OwidRawGdocBlock =
| RawBlockHomepageSearch
| RawBlockHomepageIntro
| RawBlockLatestDataInsights
| RawBlockCookieNotice
| RawBlockSocials

export type OwidEnrichedGdocBlock =
Expand Down Expand Up @@ -1078,4 +1088,5 @@ export type OwidEnrichedGdocBlock =
| EnrichedBlockHomepageSearch
| EnrichedBlockHomepageIntro
| EnrichedBlockLatestDataInsights
| EnrichedBlockCookieNotice
| EnrichedBlockSocials
2 changes: 2 additions & 0 deletions packages/@ourworldindata/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ export {
type RawBlockChartStory,
type RawBlockChartValue,
type RawBlockCode,
type RawBlockCookieNotice,
type RawBlockExpandableParagraph,
type RawBlockExplorerTiles,
type RawBlockGraySection,
Expand Down Expand Up @@ -233,6 +234,7 @@ export {
type EnrichedBlockChart,
type EnrichedBlockChartStory,
type EnrichedBlockCode,
type EnrichedBlockCookieNotice,
type EnrichedBlockDonorList,
type EnrichedBlockExpandableParagraph,
type EnrichedBlockExplorerTiles,
Expand Down
1 change: 1 addition & 0 deletions packages/@ourworldindata/utils/src/Util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1726,6 +1726,7 @@ export function traverseEnrichedBlock(
"chart",
"narrative-chart",
"code",
"cookie-notice",
"donors",
"horizontal-rule",
"html",
Expand Down
11 changes: 8 additions & 3 deletions site/blocks/CookiePreferences.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,14 @@
&:last-child {
margin-bottom: 0;
}
label {
text-transform: uppercase;
font-weight: bold;
.checkbox label {
display: flex;
margin-left: 0.5rem;
margin-bottom: 8px;
.label {
@include body-2-semibold;
padding-left: 16px;
line-height: 18px;
}
}
}
24 changes: 15 additions & 9 deletions site/blocks/CookiePreferences.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome/index.js"
import { faCheck } from "@fortawesome/free-solid-svg-icons"
import { SiteAnalytics } from "../SiteAnalytics.js"
import { Checkbox } from "@ourworldindata/components"

const ANALYTICS_ACTION = "cookie_preferences"
const analytics = new SiteAnalytics()
Expand All @@ -24,7 +25,7 @@ const analytics = new SiteAnalytics()
// - unique IDs for input elements in CookiePreference
// - support for in-place rendering

const CookiePreference = ({
export const CookiePreference = ({
title,
name,
consent,
Expand All @@ -51,15 +52,14 @@ const CookiePreference = ({

return (
<div className="cookie-preference">
<input
<Checkbox
id={id}
type="checkbox"
onChange={onChange}
checked={consent}
disabled={disabled}
onChange={onChange}
label={title}
data-test={`${name}-preference`}
></input>
<label htmlFor={id}>{title}</label>
disabled={disabled}
/>
<div className="description">{children}</div>
</div>
)
Expand All @@ -75,13 +75,19 @@ export const CookiePreferences = ({
dispatch: any
}): ReactPortal | null => {
const cookiePreferencesDomSlot = document.querySelector(
// This class is referenced in ArticleBlock.tsx
// If changed or removed, update it there also.
".wp-block-cookie-preferences"
)
if (!cookiePreferencesDomSlot) return null

return ReactDOM.createPortal(
<div data-test="cookie-preferences" className="cookie-preferences">
<h2>Cookie preferences</h2>
<div
data-test="cookie-preferences"
id="cookie-preferences"
className="cookie-preferences"
>
<h2>Cookie Preferences</h2>
<CookiePreference
title="Necessary cookies"
name="necessary"
Expand Down
10 changes: 10 additions & 0 deletions site/gdocs/components/ArticleBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,16 @@ export default function ArticleBlock({
className={getLayout("topic-page-intro", containerType)}
/>
))
.with({ type: "cookie-notice" }, () => {
return (
<div
className={cx(
getLayout("cookie-notice", containerType),
"wp-block-cookie-preferences"
)}
></div>
)
})
.with({ type: "key-insights" }, (block) => (
<KeyInsights
{...block}
Expand Down
Loading

0 comments on commit 99f4d29

Please sign in to comment.