Skip to content

Commit a04782b

Browse files
committed
WIP Focus management
1 parent db11fa4 commit a04782b

2 files changed

Lines changed: 69 additions & 26 deletions

File tree

src/ui/components/ContextualNoticeContainer.tsx

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,38 @@
1+
import {useEffect, useState} from 'preact/hooks';
12
import {purposesOnly} from '../utils/config';
2-
import {useConfig, useManager, useTheme} from '../utils/hooks';
3+
import {useConfig, useManager, useTheme, useTranslations} from '../utils/hooks';
4+
import {template} from '../utils/template';
5+
6+
type ContextualNoticeState = 'enabled' | 'disabling' | 'disabled';
37

48
interface ContextualNoticeContainerProps {
59
data: Record<string, string>;
10+
isEnabled: boolean;
611
}
712

8-
const ContextualNoticeContainer = ({data}: ContextualNoticeContainerProps) => {
13+
const ContextualNoticeContainer = ({
14+
data,
15+
isEnabled
16+
}: ContextualNoticeContainerProps) => {
917
const config = useConfig();
1018
const manager = useManager();
19+
const t = useTranslations();
1120
const {ContextualNotice} = useTheme();
21+
const [state, setState] = useState<ContextualNoticeState>(
22+
isEnabled ? 'enabled' : 'disabled'
23+
);
24+
25+
useEffect(() => {
26+
if (isEnabled && state !== 'enabled') {
27+
setState('enabled');
28+
}
1229

13-
if (!data?.purpose) {
30+
if (!isEnabled && state === 'enabled') {
31+
setState('disabling');
32+
}
33+
}, [isEnabled]);
34+
35+
if (state === 'disabled') {
1436
return null;
1537
}
1638

@@ -24,15 +46,30 @@ const ContextualNoticeContainer = ({data}: ContextualNoticeContainerProps) => {
2446

2547
const handleAccept = () => {
2648
manager.setConsent(purpose.id, true);
49+
setState('disabling');
50+
};
51+
52+
const handleFocusOut = () => {
53+
setState('disabled');
2754
};
2855

2956
return (
3057
<div className="orejime-Env">
31-
<ContextualNotice
32-
purpose={purpose}
33-
data={data}
34-
onAccept={handleAccept}
35-
></ContextualNotice>
58+
{state === 'enabled' ? (
59+
<ContextualNotice
60+
purpose={purpose}
61+
data={data}
62+
onAccept={handleAccept}
63+
></ContextualNotice>
64+
) : state === 'disabling' ? (
65+
<div
66+
tabIndex={-1}
67+
title={template(t.contextual.accepted, {
68+
purpose: purpose.title
69+
}).join('')}
70+
onFocusOut={handleFocusOut}
71+
/>
72+
) : null}
3673
</div>
3774
);
3875
};

src/ui/contextualConsentsEffect.tsx

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,44 @@
11
import {render} from 'preact';
2-
import {ConsentsMap, Manager} from '../core';
2+
import {ConsentsMap} from '../core/types';
3+
import Manager from '../core/Manager';
34
import {Config} from './types';
45
import Context from './components/Context';
56
import ContextualNoticeContainer from './components/ContextualNoticeContainer';
67

78
export const contextualConsentsEffect = (config: Config, manager: Manager) => {
8-
const templates = new WeakMap();
9+
const containers = new WeakMap();
910

1011
return (consents: ConsentsMap) => {
1112
Object.entries(consents).forEach(([id, state]) => {
1213
document
1314
.querySelectorAll(`template[data-contextual][data-purpose="${id}"]`)
1415
.forEach((template: HTMLTemplateElement) => {
15-
if (!templates.has(template)) {
16+
if (!containers.has(template)) {
1617
const container = document.createElement('div');
1718
container.style.display = 'contents';
18-
template.insertAdjacentElement('afterend', container);
19-
templates.set(template, container);
19+
20+
// The container is inserted before the template, so if
21+
// the user allows cookies from inside, the revealed
22+
// content is always after.
23+
template.insertAdjacentElement('beforeend', container);
24+
containers.set(template, container);
2025
}
2126

27+
const container = containers.get(template);
28+
2229
render(
23-
state ? null : (
24-
<Context.Provider
25-
value={{
26-
config,
27-
manager
28-
}}
29-
>
30-
<ContextualNoticeContainer
31-
data={{...template.dataset}}
32-
/>
33-
</Context.Provider>
34-
),
35-
templates.get(template)
30+
<Context.Provider
31+
value={{
32+
config,
33+
manager
34+
}}
35+
>
36+
<ContextualNoticeContainer
37+
data={{...template.dataset}}
38+
isEnabled={!state}
39+
/>
40+
</Context.Provider>,
41+
container
3642
);
3743
});
3844
});

0 commit comments

Comments
 (0)