Skip to content

Commit f4933e9

Browse files
committed
Improved contextual notice's title configuration
A default level is now configurable. On both themes, the default title level is now `h6`. @see #152 Also, we're not passing an abstract set of options around anymore. We're parsing and validating them as to have them properly typed.
1 parent ced0bbb commit f4933e9

8 files changed

Lines changed: 50 additions & 35 deletions

File tree

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,13 @@ var orejimeConfig = {
254254
// [optional]
255255
// You can provide a custom function to unserialize the cookie contents.
256256
parse: (cookie) => JSON.parse(cookie)
257+
},
258+
259+
// [optional]
260+
contextual: {
261+
// [optional]
262+
// The default level of the consent notice title.
263+
defaultTitleLevel: 6
257264
}
258265
};
259266
```
@@ -439,6 +446,9 @@ the `template`:
439446
</template>
440447
```
441448

449+
When not specified, it will default to `6`, or the level set within
450+
`orejimeConfig.contextual.defaultTitleLevel`.
451+
442452
<details>
443453
<summary>Integration tips</summary>
444454

src/ui/ContextualConsentsEffect.tsx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import {render} from 'preact';
22
import {ConsentsMap} from '../core/types';
33
import Manager from '../core/Manager';
4-
import {Config} from './types';
4+
import {Config, TitleLevel} from './types';
55
import Context from './components/Context';
66
import ContextualNoticeContainer from './components/ContextualNoticeContainer';
77
import ConsentsEffect from '../core/ConsentsEffect';
8+
import {clamp} from './utils/numbers';
89

910
export default class ContextualConsentsEffect implements ConsentsEffect {
1011
readonly #config: Config;
@@ -36,15 +37,27 @@ export default class ContextualConsentsEffect implements ConsentsEffect {
3637
}}
3738
>
3839
<ContextualNoticeContainer
39-
purposeId={template.dataset.purpose}
40-
data={{...template.dataset}}
40+
{...this.#parseNoticeData(template.dataset)}
4141
isEnabled={isEnabled}
4242
/>
4343
</Context.Provider>,
4444
this.#getNoticeContainer(template)
4545
);
4646
}
4747

48+
#parseNoticeData(data: DOMStringMap) {
49+
return {
50+
purposeId: data.purpose,
51+
titleLevel: clamp(
52+
parseInt(data.titleLevel, 10)
53+
|| this.#config?.contextual?.defaultTitleLevel
54+
|| 6,
55+
1,
56+
6
57+
) as TitleLevel
58+
};
59+
}
60+
4861
#getNoticeContainer(template: HTMLTemplateElement) {
4962
if (!this.#containers.has(template)) {
5063
const container = document.createElement('div');

src/ui/components/ContextualNoticeContainer.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@ import {useState} from 'preact/hooks';
22
import {purposesOnly} from '../utils/config';
33
import {useConfig, useManager, useTheme, useTranslations} from '../utils/hooks';
44
import {template} from '../utils/template';
5-
import {Purpose} from '../types';
5+
import {Purpose, TitleLevel} from '../types';
66

77
interface ContextualNoticeContainerProps {
88
purposeId: Purpose['id'];
9-
data: Record<string, string>;
9+
titleLevel: TitleLevel;
1010
isEnabled: boolean;
1111
}
1212

1313
const ContextualNoticeContainer = ({
1414
purposeId,
15-
data,
15+
titleLevel,
1616
isEnabled
1717
}: ContextualNoticeContainerProps) => {
1818
const config = useConfig();
@@ -45,7 +45,7 @@ const ContextualNoticeContainer = ({
4545
{isEnabled ? (
4646
<ContextualNotice
4747
purpose={purpose}
48-
data={data}
48+
titleLevel={titleLevel}
4949
privacyPolicyUrl={config.privacyPolicyUrl}
5050
onAccept={() => {
5151
manager.setConsent(purpose.id, true);
Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
import {FunctionComponent} from 'preact';
2-
import {Purpose} from '../../types';
2+
import {Purpose, TitleLevel} from '../../types';
33

4-
export interface ContextualNoticeOptions extends Record<string, string> {
5-
titleLevel?: '1' | '2' | '3' | '4' | '5' | '6';
6-
}
7-
8-
export interface ContextualNoticeProps<Data extends ContextualNoticeOptions> {
4+
export interface ContextualNoticeProps {
95
purpose: Purpose;
10-
data: Data;
6+
titleLevel: TitleLevel;
117
privacyPolicyUrl: string;
128
onAccept: () => void;
139
}
1410

15-
export type ContextualNoticeComponent<
16-
Data extends ContextualNoticeOptions = ContextualNoticeOptions
17-
> = FunctionComponent<ContextualNoticeProps<Data>>;
11+
export type ContextualNoticeComponent =
12+
FunctionComponent<ContextualNoticeProps>;

src/ui/themes/dsfr/ContextualNotice.tsx

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,14 @@
11
import {useTranslations} from '../../utils/hooks';
2-
import type {
3-
ContextualNoticeComponent,
4-
ContextualNoticeOptions
5-
} from '../../components/types/ContextualNotice';
2+
import type {ContextualNoticeComponent} from '../../components/types/ContextualNotice';
63
import {template} from '../../utils/template';
74

85
const ContextualNotice: ContextualNoticeComponent = ({
96
purpose,
10-
data,
7+
titleLevel,
118
onAccept
129
}) => {
1310
const t = useTranslations();
14-
const {titleLevel} = data;
15-
const TitleTag: `h${ContextualNoticeOptions['titleLevel']}` = titleLevel
16-
? `h${titleLevel}`
17-
: 'h4';
18-
11+
const TitleTag: `h${typeof titleLevel}` = `h${titleLevel}`;
1912
const templateProps = {
2013
purpose: purpose.title
2114
};

src/ui/themes/standard/ContextualNotice.tsx

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
11
import {useTranslations} from '../../utils/hooks';
2-
import type {
3-
ContextualNoticeComponent,
4-
ContextualNoticeOptions
5-
} from '../../components/types/ContextualNotice';
2+
import type {ContextualNoticeComponent} from '../../components/types/ContextualNotice';
63
import {template} from '../../utils/template';
74

85
const ContextualNotice: ContextualNoticeComponent = ({
96
purpose,
10-
data,
7+
titleLevel,
118
onAccept,
129
privacyPolicyUrl
1310
}) => {
1411
const t = useTranslations();
15-
const {titleLevel} = data;
16-
const TitleTag: `h${ContextualNoticeOptions['titleLevel']}` | 'strong' =
17-
titleLevel ? `h${titleLevel}` : 'strong';
12+
const TitleTag: `h${typeof titleLevel}` = `h${titleLevel}`;
1813
const templateProps = {
1914
purpose: purpose.title,
2015
privacyPolicy: (

src/ui/types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ export type ImageAttributes = {
8686

8787
export type ImageDescriptor = string | ImageAttributes;
8888

89+
export type TitleLevel = 1 | 2 | 3 | 4 | 5 | 6;
90+
91+
export interface ContextualConfig {
92+
defaultTitleLevel?: TitleLevel;
93+
}
94+
8995
export interface Config {
9096
theme: Theme;
9197
orejimeElement?: ElementReference;
@@ -96,5 +102,6 @@ export interface Config {
96102
forceBanner: boolean;
97103
forceModal: boolean;
98104
privacyPolicyUrl: string;
105+
contextual?: ContextualConfig;
99106
translations: Translations;
100107
}

src/ui/utils/numbers.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export const clamp = (value: number, min: number, max: number) =>
2+
Math.min(Math.max(value, min), max);

0 commit comments

Comments
 (0)