Skip to content

Commit 284f20a

Browse files
committed
Refactor app-state
1 parent a3be252 commit 284f20a

File tree

8 files changed

+99
-93
lines changed

8 files changed

+99
-93
lines changed

src/components/App.tsx

+3-44
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
import React, { useCallback, useEffect, useState } from 'react';
1+
import React from 'react';
22
import { AppContext } from '../../common/appContext';
33
import { AppTopSection } from './top-section/AppTopSection';
44
import { AppLeftSection } from './left-section/AppLeftSection';
55
import { AppMainSection } from './main-section/AppMainSection';
6-
import { useAppState } from '../state/useAppState';
7-
import { CmsContent } from '../../common/cms-documents/content';
8-
import { CmsCategoryListItem } from '../../common/cms-documents/category';
6+
import { AppStateProvider } from '../state/useAppState';
97

108
import style from './App.module.css';
119

@@ -14,49 +12,10 @@ type Props = {
1412
};
1513

1614
export const App = ({ appContext }: Props) => {
17-
const [selectedContent, _setSelectedContent] = useState<CmsContent | null>(null);
18-
const [selectedCategory, setSelectedCategory] = useState<CmsCategoryListItem | null>(null);
19-
const [contentSelectorOpen, setContentSelectorOpen] = useState<boolean>(false);
20-
21-
const { AppStateProvider } = useAppState();
22-
2315
const { cmsName } = appContext;
2416

25-
const setSelectedContent = useCallback(
26-
(content: CmsContent | null, toHistory: boolean = true) => {
27-
_setSelectedContent(content);
28-
if (toHistory) {
29-
window.history.pushState(
30-
{ ...window.history.state, content },
31-
'',
32-
`${appContext.basePath}/${content ? content.versionKey : ''}`
33-
);
34-
}
35-
},
36-
[appContext]
37-
);
38-
39-
useEffect(() => {
40-
const onPopState = (e: PopStateEvent) => {
41-
setSelectedContent(e.state?.content || null, false);
42-
};
43-
44-
window.addEventListener('popstate', onPopState);
45-
return () => window.removeEventListener('popstate', onPopState);
46-
}, [setSelectedContent]);
47-
4817
return (
49-
<AppStateProvider
50-
value={{
51-
appContext,
52-
selectedContent,
53-
setSelectedContent,
54-
selectedCategory,
55-
setSelectedCategory,
56-
contentSelectorOpen,
57-
setContentSelectorOpen,
58-
}}
59-
>
18+
<AppStateProvider appContext={appContext}>
6019
<div className={style.root}>
6120
<AppTopSection cmsName={cmsName} />
6221
<AppLeftSection />

src/components/left-section/search/search-input/SearchInput.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import { ContentSearchParams, ContentSearchResult } from '../../../../../common/
44
import { useApiFetch } from '../../../../fetch/useApiFetch';
55
import { classNames } from '../../../../utils/classNames';
66
import { SearchSettings } from './search-settings/SearchSettings';
7-
import { getInitialSearchParams, initialSearchParams } from './params-initial-state';
7+
import { getInitialSearchParams } from './params-initial-state';
88
import { useAppState } from '../../../../state/useAppState';
99

1010
import style from './SearchInput.module.css';
11+
import { initialSearchParams } from '../../../../state/useSearchState';
1112

1213
type Props = {
1314
setSearchResult: (searchResult: ContentSearchResult | null) => void;

src/components/left-section/search/search-input/params-initial-state.ts

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
import { ContentSearchParams } from '../../../../../common/contentSearch';
22
import Cookies from 'js-cookie';
3+
import { initialSearchParams } from '../../../../state/useSearchState';
34

45
const getCookieKey = (basePath: string) => `cms-archive-search-settings${basePath}`;
56

6-
export const initialSearchParams: ContentSearchParams = {
7-
from: 0,
8-
size: 50,
9-
withChildCategories: true,
10-
} as const;
11-
127
export const getInitialSearchParams = (basePath: string): ContentSearchParams => {
138
const cookieValue = Cookies.get(getCookieKey(basePath));
149

src/components/left-section/search/search-input/search-settings/SearchSettings.module.css

-10
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,6 @@
5959
align-items: center;
6060
}
6161

62-
.withHelp {
63-
display: flex;
64-
gap: 0.5rem;
65-
align-items: center;
66-
:global(.navds-popover__content) {
67-
font-size: var(--a-font-size-small);
68-
line-height: var(--a-font-line-height-medium);
69-
}
70-
}
71-
7262
.categoriesSelector {
7363
ul {
7464
gap: 0.25rem;

src/components/left-section/search/search-input/search-settings/SearchSettings.tsx

+2-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useState } from 'react';
2-
import { Button, HelpText, Label, Radio, RadioGroup, UNSAFE_Combobox } from '@navikt/ds-react';
2+
import { Button, Label, Radio, RadioGroup, UNSAFE_Combobox } from '@navikt/ds-react';
33
import { ChevronDownIcon, XMarkIcon } from '@navikt/aksel-icons';
44
import { ContentSearchParams } from '../../../../../../common/contentSearch';
55
import { classNames } from '../../../../../utils/classNames';
@@ -70,15 +70,7 @@ export const SearchSettings = ({ searchParams, setSearchParams, reset }: Props)
7070
onChange={(value) => updateSearchParams({ type: value })}
7171
>
7272
<Radio value={'titles'}>{'Tittel'}</Radio>
73-
<span className={style.withHelp}>
74-
<Radio value={'locations'}>{'URL'}</Radio>
75-
<HelpText wrapperClassName={style.help}>
76-
{'Prefix-søk på pathname. F.eks. vil '}
77-
<code>{'https://www.nav.no/no/person/arbeid'}</code>
78-
{' gi treff på alle sider med en path som starter med '}
79-
<code>{'/no/person/arbeid'}</code>
80-
</HelpText>
81-
</span>
73+
<Radio value={'locations'}>{'URL'}</Radio>
8274
<Radio value={'all'}>{'Alt innhold'}</Radio>
8375
</RadioGroup>
8476
<RadioGroup
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import React from 'react';
2+
3+
type Props = {
4+
children: React.ReactNode;
5+
};
6+
7+
export const AppStateProvider = ({ children }: Props) => {};

src/state/useAppState.tsx

+52-22
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createContext, useContext } from 'react';
1+
import React, { createContext, useCallback, useContext, useEffect, useState } from 'react';
22
import { AppContext, appErrorContext } from '../../common/appContext';
33
import { CmsContent } from '../../common/cms-documents/content';
44
import { CmsCategoryListItem } from '../../common/cms-documents/category';
@@ -13,7 +13,6 @@ type AppState = {
1313
setContentSelectorOpen: (isOpen: boolean) => void;
1414
};
1515

16-
// eslint-disable-next-line react-refresh/only-export-components
1716
const AppStateContext = createContext<AppState>({
1817
appContext: appErrorContext,
1918
selectedContent: null,
@@ -25,24 +24,55 @@ const AppStateContext = createContext<AppState>({
2524
});
2625

2726
export const useAppState = () => {
28-
const {
29-
appContext,
30-
selectedContent,
31-
setSelectedContent,
32-
selectedCategory,
33-
setSelectedCategory,
34-
contentSelectorOpen,
35-
setContentSelectorOpen,
36-
} = useContext(AppStateContext);
37-
38-
return {
39-
AppStateProvider: AppStateContext.Provider,
40-
appContext,
41-
selectedContent,
42-
setSelectedContent,
43-
selectedCategory,
44-
setSelectedCategory,
45-
contentSelectorOpen,
46-
setContentSelectorOpen,
47-
};
27+
return useContext(AppStateContext);
28+
};
29+
30+
type ProviderProps = {
31+
appContext: AppContext;
32+
children: React.ReactNode;
33+
};
34+
35+
export const AppStateProvider = ({ appContext, children }: ProviderProps) => {
36+
const [selectedContent, setSelectedContent] = useState<CmsContent | null>(null);
37+
const [selectedCategory, setSelectedCategory] = useState<CmsCategoryListItem | null>(null);
38+
const [contentSelectorOpen, setContentSelectorOpen] = useState<boolean>(false);
39+
40+
const setSelectedContentWithHistory = useCallback(
41+
(content: CmsContent | null, toHistory: boolean = true) => {
42+
setSelectedContent(content);
43+
if (toHistory) {
44+
window.history.pushState(
45+
{ ...window.history.state, content },
46+
'',
47+
`${appContext.basePath}/${content ? content.versionKey : ''}`
48+
);
49+
}
50+
},
51+
[appContext]
52+
);
53+
54+
useEffect(() => {
55+
const onPopState = (e: PopStateEvent) => {
56+
setSelectedContentWithHistory(e.state?.content || null, false);
57+
};
58+
59+
window.addEventListener('popstate', onPopState);
60+
return () => window.removeEventListener('popstate', onPopState);
61+
}, [setSelectedContentWithHistory]);
62+
63+
return (
64+
<AppStateContext.Provider
65+
value={{
66+
appContext,
67+
selectedContent,
68+
setSelectedContent: setSelectedContentWithHistory,
69+
selectedCategory,
70+
setSelectedCategory,
71+
contentSelectorOpen,
72+
setContentSelectorOpen,
73+
}}
74+
>
75+
{children}
76+
</AppStateContext.Provider>
77+
);
4878
};

src/state/useSearchState.ts

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import React, { createContext, useContext, useState } from 'react';
2+
import { appErrorContext } from '../../common/appContext';
3+
import { ContentSearchParams, ContentSearchResult } from '../../common/contentSearch';
4+
5+
type SearchState = {
6+
searchResult: ContentSearchResult | null;
7+
searchParams: ContentSearchParams;
8+
};
9+
10+
export const initialSearchParams: ContentSearchParams = {
11+
from: 0,
12+
size: 50,
13+
withChildCategories: true,
14+
} as const;
15+
16+
const SearchStateContext = createContext<SearchState>({
17+
searchResult: null,
18+
searchParams: initialSearchParams,
19+
});
20+
21+
export const useSearchState = () => {
22+
const { searchParams, searchResult } = useContext(SearchStateContext);
23+
24+
return {
25+
searchParams,
26+
searchResult,
27+
};
28+
};
29+
30+
export const SearchProvider = ({ children }: { children: React.ReactNode }) => {
31+
const [result, setResult] = useState();
32+
};

0 commit comments

Comments
 (0)