Skip to content

Commit ddf8ad5

Browse files
committed
Endrer UI for valg av kategorier i søket
1 parent c6f276e commit ddf8ad5

File tree

9 files changed

+101
-65
lines changed

9 files changed

+101
-65
lines changed

src/components/common/paginator/Paginator.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ type Props = {
1010
};
1111

1212
export const Paginator = ({ numPages, pageNumber, onPageChange }: Props) => {
13-
if (numPages === 0) {
13+
if (numPages <= 1) {
1414
return null;
1515
}
1616

src/components/left-section/AppLeftSection.module.css

+1
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,6 @@
5858
right: 0;
5959
visibility: visible;
6060
opacity: 1;
61+
background-color: var(--a-white);
6162
}
6263
}

src/components/left-section/categories/CategoriesMenu.tsx

+14-2
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@ import React from 'react';
22
import { CmsCategoryListItem } from '../../../../common/cms-documents/category';
33
import { ChevronDownIcon, ChevronRightIcon } from '@navikt/aksel-icons';
44
import { TreeView } from '@mui/x-tree-view';
5-
import { CategoriesList } from './CategoriesList';
5+
import { RootCategory } from './root-category/RootCategory';
6+
import { CheckboxGroup } from '@navikt/ds-react';
7+
import { useSearchState } from '../../../context/search-state/useSearchState';
68

79
type Props = {
810
rootCategories: CmsCategoryListItem[];
911
className?: string;
1012
};
1113

1214
export const CategoriesMenu = ({ rootCategories, className }: Props) => {
15+
const { updateSearchParams } = useSearchState();
16+
1317
return (
1418
<TreeView
1519
defaultExpandIcon={<ChevronRightIcon />}
@@ -18,7 +22,15 @@ export const CategoriesMenu = ({ rootCategories, className }: Props) => {
1822
root: className,
1923
}}
2024
>
21-
<CategoriesList categories={rootCategories} />
25+
<CheckboxGroup
26+
legend={'Velg kategorier for søket'}
27+
hideLegend={true}
28+
onChange={(values) => updateSearchParams({ categoryKeys: values })}
29+
>
30+
{rootCategories.map((category) => (
31+
<RootCategory category={category} key={category.key} />
32+
))}
33+
</CheckboxGroup>
2234
</TreeView>
2335
);
2436
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
.rootCategory {
2+
position: relative;
3+
display: flex;
4+
align-items: flex-start;
5+
}
6+
7+
.checkbox {
8+
position: absolute;
9+
visibility: hidden;
10+
opacity: 0;
11+
left: -2rem;
12+
overflow: hidden;
13+
margin-left: 0.5rem;
14+
padding: 0.0625rem 0;
15+
background-color: var(--a-white);
16+
17+
transition-duration: 150ms;
18+
transition-timing-function: ease-out;
19+
transition-property: visibility, opacity, left;
20+
21+
&.open {
22+
left: 0;
23+
opacity: 1;
24+
visibility: visible;
25+
}
26+
27+
& > label:global(.navds-checkbox__label) {
28+
padding: 0;
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import React from 'react';
2+
import { CmsCategoryListItem } from '../../../../../common/cms-documents/category';
3+
import { Category } from '../category/Category';
4+
import { Checkbox } from '@navikt/ds-react';
5+
import { useSearchState } from '../../../../context/search-state/useSearchState';
6+
import { classNames } from '../../../../utils/classNames';
7+
8+
import style from './RootCategory.module.css';
9+
10+
type Props = {
11+
category: CmsCategoryListItem;
12+
};
13+
14+
export const RootCategory = ({ category }: Props) => {
15+
const { searchSettingsIsOpen } = useSearchState();
16+
17+
return (
18+
<div className={style.rootCategory}>
19+
<Checkbox
20+
size={'small'}
21+
value={category.key}
22+
className={classNames(style.checkbox, searchSettingsIsOpen && style.open)}
23+
hideLabel={true}
24+
>
25+
{`Filtrer ${category.title} i søket`}
26+
</Checkbox>
27+
<Category category={category} />
28+
</div>
29+
);
30+
};

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

+3-10
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
visibility: hidden;
2929
overflow: hidden;
3030

31-
transition-duration: 250ms;
31+
transition-duration: 200ms;
3232
transition-timing-function: ease-out;
3333
transition-property: visibility, max-height, padding, overflow;
3434

@@ -38,11 +38,11 @@
3838

3939
background-color: var(--a-gray-200);
4040
border-radius: var(--a-border-radius-medium);
41-
margin-bottom: 0.25rem;
41+
margin-bottom: 0.5rem;
4242
padding: 0 0.5rem;
4343

4444
&.open {
45-
max-height: 500px;
45+
max-height: 150px;
4646
visibility: visible;
4747
padding: 0.5rem;
4848
overflow: visible;
@@ -58,10 +58,3 @@
5858
display: flex;
5959
align-items: center;
6060
}
61-
62-
.categoriesSelector {
63-
ul {
64-
gap: 0.25rem;
65-
font-size: 0.875rem;
66-
}
67-
}
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,21 @@
1-
import React, { useState } from 'react';
2-
import { Button, Label, Radio, RadioGroup, UNSAFE_Combobox } from '@navikt/ds-react';
1+
import React from 'react';
2+
import { Button, Label, Radio, RadioGroup } from '@navikt/ds-react';
33
import { ChevronDownIcon, XMarkIcon } from '@navikt/aksel-icons';
44
import { classNames } from '../../../../../utils/classNames';
5-
import { CmsCategoryListItem } from '../../../../../../common/cms-documents/category';
6-
import { useAppState } from '../../../../../context/app-state/useAppState';
75
import { useSearchState } from '../../../../../context/search-state/useSearchState';
86

97
import style from './SearchSettings.module.css';
108

119
export const SearchSettings = () => {
12-
const [isOpen, setIsOpen] = useState(false);
10+
const {
11+
searchParams,
12+
updateSearchParams,
13+
resetSearchSettings,
14+
searchSettingsIsOpen,
15+
setSearchSettingsIsOpen,
16+
} = useSearchState();
1317

14-
const { appContext } = useAppState();
15-
const { rootCategories } = appContext;
16-
17-
const { searchParams, updateSearchParams, resetSearchSettings } = useSearchState();
18-
const { sort, categoryKeys, type, isCustom } = searchParams;
19-
20-
const { titlesToKeys, keysToTitles } = createKeysTitlesMaps(rootCategories);
21-
const categoryKeysSelected = new Set<string>(categoryKeys);
22-
const categoryTitlesSelected = [...categoryKeysSelected].map((key) => keysToTitles[key]);
23-
const categoryTitlesAll = Object.keys(titlesToKeys);
18+
const { sort, type, isCustom } = searchParams;
2419

2520
return (
2621
<div className={style.container}>
@@ -42,14 +37,16 @@ export const SearchSettings = () => {
4237
size={'xsmall'}
4338
variant={'tertiary'}
4439
className={style.toggle}
45-
onClick={() => setIsOpen(!isOpen)}
40+
onClick={() => setSearchSettingsIsOpen(!searchSettingsIsOpen)}
4641
>
4742
{'Tilpass søket'}
48-
<ChevronDownIcon className={classNames(style.icon, isOpen && style.open)} />
43+
<ChevronDownIcon
44+
className={classNames(style.icon, searchSettingsIsOpen && style.open)}
45+
/>
4946
</Button>
5047
</div>
5148
</div>
52-
<div className={classNames(style.settings, isOpen && style.open)}>
49+
<div className={classNames(style.settings, searchSettingsIsOpen && style.open)}>
5350
<div className={style.radioGroups}>
5451
<RadioGroup
5552
size={'small'}
@@ -72,41 +69,7 @@ export const SearchSettings = () => {
7269
<Radio value={'datetime'}>{'Sist endret'}</Radio>
7370
</RadioGroup>
7471
</div>
75-
<UNSAFE_Combobox
76-
label={'Avgrens søket til valgte kategorier:'}
77-
size={'small'}
78-
className={style.categoriesSelector}
79-
clearButton={true}
80-
isMultiSelect={true}
81-
allowNewValues={false}
82-
options={categoryTitlesAll}
83-
selectedOptions={categoryTitlesSelected}
84-
onToggleSelected={(value, isSelected) => {
85-
const key = titlesToKeys[value];
86-
if (isSelected) {
87-
categoryKeysSelected.add(key);
88-
} else {
89-
categoryKeysSelected.delete(key);
90-
}
91-
92-
updateSearchParams({ categoryKeys: [...categoryKeysSelected] });
93-
}}
94-
/>
9572
</div>
9673
</div>
9774
);
9875
};
99-
100-
const createKeysTitlesMaps = (categories: CmsCategoryListItem[]) => {
101-
return categories.reduce<{
102-
keysToTitles: Record<string, string>;
103-
titlesToKeys: Record<string, string>;
104-
}>(
105-
(acc, category) => {
106-
acc.titlesToKeys[category.title] = category.key;
107-
acc.keysToTitles[category.key] = category.title;
108-
return acc;
109-
},
110-
{ keysToTitles: {}, titlesToKeys: {} }
111-
);
112-
};

src/context/search-state/SearchStateContext.ts

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ export type SearchState = {
66
setSearchResult: (result: ContentSearchResult) => void;
77
searchResultIsOpen: boolean;
88
setSearchResultIsOpen: (isOpen: boolean) => void;
9+
searchSettingsIsOpen: boolean;
10+
setSearchSettingsIsOpen: (isOpen: boolean) => void;
911
searchParams: ContentSearchParams;
1012
setSearchParams: (params: ContentSearchParams) => void;
1113
updateSearchParams: (params: Partial<ContentSearchParams>) => void;
@@ -31,6 +33,8 @@ export const SearchStateContext = createContext<SearchState>({
3133
setSearchResult: () => ({}),
3234
searchResultIsOpen: false,
3335
setSearchResultIsOpen: () => ({}),
36+
searchSettingsIsOpen: false,
37+
setSearchSettingsIsOpen: () => ({}),
3438
searchParams: initialSearchParams,
3539
setSearchParams: () => ({}),
3640
updateSearchParams: () => ({}),

src/context/search-state/SearchStateProvider.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const SearchStateProvider = ({ children }: Props) => {
1919
getInitialSearchParams(basePath)
2020
);
2121
const [searchResultIsOpen, setSearchResultIsOpen] = useState(false);
22+
const [searchSettingsIsOpen, setSearchSettingsIsOpen] = useState(false);
2223

2324
const updateSearchParams = (params: Partial<ContentSearchParams>) => {
2425
const newParams: ContentSearchParams = { ...searchParams, ...params, isCustom: true };
@@ -56,6 +57,8 @@ export const SearchStateProvider = ({ children }: Props) => {
5657
setSearchParams,
5758
searchResultIsOpen,
5859
setSearchResultIsOpen,
60+
searchSettingsIsOpen,
61+
setSearchSettingsIsOpen,
5962
updateSearchParams,
6063
resetSearchSettings,
6164
runSearch,

0 commit comments

Comments
 (0)