@ndla/ui 43.0.0 → 43.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/es/Article/ArticleNotions.js +46 -53
  2. package/es/Filter/FilterButtons.js +49 -53
  3. package/es/Filter/FilterListPhone.js +78 -71
  4. package/es/LearningPaths/LearningPathMenuModalWrapper.js +39 -28
  5. package/es/LicenseByline/EmbedByline.js +14 -7
  6. package/es/LicenseByline/LicenseDescription.js +2 -18
  7. package/es/Masthead/MastheadSearchModal.js +31 -35
  8. package/es/NDLAFilm/AboutNdlaFilm.js +16 -20
  9. package/es/NDLAFilm/FilmMovieSearch.js +43 -11
  10. package/es/ResourcesWrapper/ResourcesTopicTitle.js +36 -44
  11. package/es/Search/ToggleSearchButton.js +7 -6
  12. package/es/SearchTypeResult/PopupFilter.js +55 -69
  13. package/es/SearchTypeResult/SearchNotionsResult.js +9 -7
  14. package/es/SearchTypeResult/components/ItemContexts.js +41 -45
  15. package/es/SearchTypeResult/components/SubjectFilters.js +16 -17
  16. package/es/Topic/Topic.js +41 -45
  17. package/es/locale/messages-en.js +1 -0
  18. package/es/locale/messages-nb.js +1 -0
  19. package/es/locale/messages-nn.js +1 -0
  20. package/es/locale/messages-se.js +1 -0
  21. package/es/locale/messages-sma.js +1 -0
  22. package/lib/Article/ArticleNotions.js +45 -52
  23. package/lib/Filter/FilterButtons.js +48 -52
  24. package/lib/Filter/FilterListPhone.js +76 -69
  25. package/lib/LearningPaths/LearningPathMenuModalWrapper.js +47 -35
  26. package/lib/LicenseByline/EmbedByline.d.ts +1 -1
  27. package/lib/LicenseByline/EmbedByline.js +15 -8
  28. package/lib/LicenseByline/LicenseDescription.d.ts +1 -1
  29. package/lib/LicenseByline/LicenseDescription.js +10 -23
  30. package/lib/Masthead/MastheadSearchModal.js +29 -32
  31. package/lib/NDLAFilm/AboutNdlaFilm.js +15 -18
  32. package/lib/NDLAFilm/FilmMovieSearch.d.ts +1 -2
  33. package/lib/NDLAFilm/FilmMovieSearch.js +46 -11
  34. package/lib/ResourcesWrapper/ResourcesTopicTitle.js +35 -42
  35. package/lib/Search/ToggleSearchButton.d.ts +2 -1
  36. package/lib/Search/ToggleSearchButton.js +9 -6
  37. package/lib/SearchTypeResult/PopupFilter.d.ts +1 -3
  38. package/lib/SearchTypeResult/PopupFilter.js +54 -68
  39. package/lib/SearchTypeResult/SearchNotionsResult.js +9 -7
  40. package/lib/SearchTypeResult/components/ItemContexts.js +40 -44
  41. package/lib/SearchTypeResult/components/SubjectFilters.js +16 -17
  42. package/lib/Topic/Topic.js +40 -44
  43. package/lib/locale/messages-en.d.ts +1 -0
  44. package/lib/locale/messages-en.js +1 -0
  45. package/lib/locale/messages-nb.d.ts +1 -0
  46. package/lib/locale/messages-nb.js +1 -0
  47. package/lib/locale/messages-nn.d.ts +1 -0
  48. package/lib/locale/messages-nn.js +1 -0
  49. package/lib/locale/messages-se.d.ts +1 -0
  50. package/lib/locale/messages-se.js +1 -0
  51. package/lib/locale/messages-sma.d.ts +1 -0
  52. package/lib/locale/messages-sma.js +1 -0
  53. package/package.json +10 -10
  54. package/src/Article/ArticleNotions.tsx +29 -35
  55. package/src/Filter/FilterButtons.tsx +28 -34
  56. package/src/Filter/FilterListPhone.tsx +63 -62
  57. package/src/LearningPaths/LearningPathMenuModalWrapper.tsx +19 -18
  58. package/src/LicenseByline/EmbedByline.tsx +9 -3
  59. package/src/LicenseByline/LicenseDescription.tsx +6 -7
  60. package/src/Masthead/MastheadSearchModal.tsx +21 -29
  61. package/src/NDLAFilm/AboutNdlaFilm.tsx +11 -10
  62. package/src/NDLAFilm/FilmMovieSearch.tsx +32 -9
  63. package/src/ResourcesWrapper/ResourcesTopicTitle.tsx +23 -27
  64. package/src/Search/ToggleSearchButton.tsx +15 -12
  65. package/src/SearchTypeResult/PopupFilter.tsx +55 -70
  66. package/src/SearchTypeResult/SearchNotionsResult.tsx +5 -2
  67. package/src/SearchTypeResult/components/ItemContexts.tsx +23 -28
  68. package/src/SearchTypeResult/components/SubjectFilters.tsx +9 -12
  69. package/src/Topic/Topic.tsx +15 -17
  70. package/src/locale/messages-en.ts +1 -0
  71. package/src/locale/messages-nb.ts +1 -0
  72. package/src/locale/messages-nn.ts +1 -0
  73. package/src/locale/messages-se.ts +1 -0
  74. package/src/locale/messages-sma.ts +1 -0
  75. package/es/NDLAFilm/CategorySelect.js +0 -135
  76. package/lib/NDLAFilm/CategorySelect.d.ts +0 -16
  77. package/lib/NDLAFilm/CategorySelect.js +0 -144
  78. package/src/NDLAFilm/CategorySelect.tsx +0 -197
@@ -1,5 +1,5 @@
1
- import React, { ReactNode, useState } from 'react';
2
- import { Drawer } from '@ndla/modal';
1
+ import React, { ReactNode, useCallback, useState } from 'react';
2
+ import { Drawer, Modal, ModalTrigger } from '@ndla/modal';
3
3
  import { IconButtonV2 as IconButton } from '@ndla/button';
4
4
  import { Cross } from '@ndla/icons/action';
5
5
  import styled from '@emotion/styled';
@@ -63,42 +63,34 @@ const StyledHeader = styled.div`
63
63
  const MastheadSearchModal = ({ onClose: onSearchClose, children, hideOnNarrowScreen, ndlaFilm }: Props) => {
64
64
  const { t } = useTranslation();
65
65
  const [isOpen, setIsOpen] = useState(false);
66
+
67
+ const closeModal = useCallback(() => {
68
+ onSearchClose();
69
+ setIsOpen(false);
70
+ }, [onSearchClose]);
71
+
66
72
  return (
67
- <>
68
- <ToggleSearchButton hideOnNarrowScreen={hideOnNarrowScreen} onClick={() => setIsOpen(true)} ndlaFilm={ndlaFilm}>
69
- {t('masthead.menu.search')}
70
- </ToggleSearchButton>
73
+ <Modal open={isOpen} onOpenChange={setIsOpen}>
74
+ <ModalTrigger>
75
+ <ToggleSearchButton hideOnNarrowScreen={hideOnNarrowScreen} onClick={() => setIsOpen(true)} ndlaFilm={ndlaFilm}>
76
+ {t('masthead.menu.search')}
77
+ </ToggleSearchButton>
78
+ </ModalTrigger>
71
79
  <StyledDrawer
72
- controlled
73
80
  aria-label={t('searchPage.searchFieldPlaceholder')}
74
81
  position="top"
75
82
  expands
76
83
  size="small"
77
- animation="slideIn"
78
84
  animationDuration={200}
79
- isOpen={isOpen}
80
- onClose={() => {
81
- setIsOpen(false);
82
- onSearchClose();
83
- }}
84
85
  >
85
- {(closeModal) => (
86
- <>
87
- <StyledHeader>
88
- {children(closeModal)}
89
- <IconButton
90
- aria-label={t('welcomePage.closeSearch')}
91
- variant="ghost"
92
- colorTheme="light"
93
- onClick={closeModal}
94
- >
95
- <Cross className="c-icon--medium" />
96
- </IconButton>
97
- </StyledHeader>
98
- </>
99
- )}
86
+ <StyledHeader>
87
+ {children(closeModal)}
88
+ <IconButton aria-label={t('welcomePage.closeSearch')} variant="ghost" colorTheme="light" onClick={closeModal}>
89
+ <Cross className="c-icon--medium" />
90
+ </IconButton>
91
+ </StyledHeader>
100
92
  </StyledDrawer>
101
- </>
93
+ </Modal>
102
94
  );
103
95
  };
104
96
 
@@ -1,7 +1,7 @@
1
1
  import React, { ReactNode } from 'react';
2
2
  import { useTranslation } from 'react-i18next';
3
3
  import styled from '@emotion/styled';
4
- import { ModalHeader, ModalBody, ModalCloseButton, Modal } from '@ndla/modal';
4
+ import { ModalHeader, ModalBody, ModalCloseButton, Modal, ModalTrigger, ModalContent } from '@ndla/modal';
5
5
  import { colors, spacing, mq, breakpoints } from '@ndla/core';
6
6
  import { ButtonV2 as Button } from '@ndla/button';
7
7
  import VisualElement from './VisualElement';
@@ -64,15 +64,16 @@ const AboutNdlaFilm = ({ aboutNDLAVideo, moreAboutNdlaFilm }: Props) => {
64
64
  <div>
65
65
  <h2 id={titleId}>{aboutNDLAVideo.title}</h2>
66
66
  <p>{aboutNDLAVideo.description}</p>
67
- <Modal size="full" activateButton={<Button variant="link">{t('ndlaFilm.about.more')}</Button>}>
68
- {(onClose) => (
69
- <>
70
- <ModalHeader>
71
- <ModalCloseButton onClick={onClose} />
72
- </ModalHeader>
73
- <ModalBody>{moreAboutNdlaFilm}</ModalBody>
74
- </>
75
- )}
67
+ <Modal>
68
+ <ModalTrigger>
69
+ <Button variant="link">{t('ndlaFilm.about.more')}</Button>
70
+ </ModalTrigger>
71
+ <ModalContent size="full">
72
+ <ModalHeader>
73
+ <ModalCloseButton />
74
+ </ModalHeader>
75
+ <ModalBody>{moreAboutNdlaFilm}</ModalBody>
76
+ </ModalContent>
76
77
  </Modal>
77
78
  </div>
78
79
  </StyledAside>
@@ -6,12 +6,12 @@
6
6
  *
7
7
  */
8
8
 
9
- import React from 'react';
9
+ import React, { useCallback, useMemo } from 'react';
10
10
  import SafeLink from '@ndla/safelink';
11
11
  import { useTranslation } from 'react-i18next';
12
12
  import styled from '@emotion/styled';
13
13
  import { spacing, mq, breakpoints, colors } from '@ndla/core';
14
- import CategorySelect from './CategorySelect';
14
+ import { Option, Select, SingleValue } from '@ndla/select';
15
15
  import { MovieResourceType } from './types';
16
16
  import { OneColumn } from '..';
17
17
  import { StyledHeadingH2 } from './filmStyles';
@@ -59,7 +59,6 @@ interface Props {
59
59
  onChangeResourceType: (resourceType?: string) => void;
60
60
  resourceTypeSelected?: MovieResourceType;
61
61
  resourceTypes: MovieResourceType[];
62
- ariaControlId: string;
63
62
  skipToContentId?: string;
64
63
  }
65
64
 
@@ -68,10 +67,32 @@ const FilmMovieSearch = ({
68
67
  onChangeResourceType,
69
68
  resourceTypes,
70
69
  resourceTypeSelected,
71
- ariaControlId,
72
70
  skipToContentId,
73
71
  }: Props) => {
74
72
  const { t } = useTranslation();
73
+ const selectedOption = useMemo(() => {
74
+ if (resourceTypeSelected) {
75
+ return { value: resourceTypeSelected.id, label: resourceTypeSelected.name };
76
+ }
77
+ return { value: 'fromNdla', label: t('ndlaFilm.search.categoryFromNdla') };
78
+ }, [resourceTypeSelected, t]);
79
+
80
+ const options: Option[] = useMemo(() => {
81
+ const fromNdla = { value: 'fromNdla', label: t('ndlaFilm.search.categoryFromNdla') };
82
+ return [fromNdla].concat(resourceTypes.map((rt) => ({ value: rt.id, label: rt.name })));
83
+ }, [resourceTypes, t]);
84
+
85
+ const onChange = useCallback(
86
+ (value: SingleValue) => {
87
+ if (value?.value === 'fromNdla') {
88
+ onChangeResourceType();
89
+ } else {
90
+ onChangeResourceType(value?.value);
91
+ }
92
+ },
93
+ [onChangeResourceType],
94
+ );
95
+
75
96
  return (
76
97
  <FilmMovieSearchContainer>
77
98
  <OneColumn>
@@ -91,11 +112,13 @@ const FilmMovieSearch = ({
91
112
  </StyledUl>
92
113
  </nav>
93
114
  </TopicNavigation>
94
- <CategorySelect
95
- onChangeResourceType={onChangeResourceType}
96
- resourceTypes={resourceTypes}
97
- resourceTypeSelected={resourceTypeSelected}
98
- ariaControlId={ariaControlId}
115
+ <Select<false>
116
+ options={options}
117
+ value={selectedOption}
118
+ onChange={onChange}
119
+ colorTheme="white"
120
+ placeholder={t('ndlaFilm.search.chooseCategory')}
121
+ prefix={`${t('ndlaFilm.search.chooseCategory')} `}
99
122
  />
100
123
  </OneColumn>
101
124
  </FilmMovieSearchContainer>
@@ -1,9 +1,9 @@
1
- import React, { ReactNode } from 'react';
1
+ import React from 'react';
2
2
  import { useTranslation } from 'react-i18next';
3
3
  import { css } from '@emotion/react';
4
4
  import styled from '@emotion/styled';
5
5
  import { breakpoints, colors, fonts, mq, spacing } from '@ndla/core';
6
- import { ModalBody, ModalHeader, ModalCloseButton, Modal, ModalTitle } from '@ndla/modal';
6
+ import { ModalBody, ModalHeader, ModalCloseButton, Modal, ModalTitle, ModalTrigger, ModalContent } from '@ndla/modal';
7
7
  import Tooltip from '@ndla/tooltip';
8
8
  import { Switch } from '@ndla/switch';
9
9
  import { LearningPathQuiz } from '@ndla/icons/contentType';
@@ -185,31 +185,27 @@ const ResourcesTopicTitle = ({
185
185
  onChange={toggleAdditionalResources}
186
186
  css={invertedStyle ? invertedSwitchCSS : switchCSS}
187
187
  />
188
- <Modal
189
- wrapperFunctionForButton={(activateButton: ReactNode) => (
190
- <TooltipWrapper>
191
- <Tooltip tooltip={t('resource.dialogTooltip')}>{activateButton}</Tooltip>
192
- </TooltipWrapper>
193
- )}
194
- activateButton={
195
- <TooltipButton aria-label={t('resource.dialogTooltip')}>
196
- <HelpIcon invertedStyle={invertedStyle} />
197
- </TooltipButton>
198
- }
199
- >
200
- {(onClose: () => void) => (
201
- <>
202
- <ModalHeader>
203
- <ModalTitle>{t('resource.dialogHeading')}</ModalTitle>
204
- <ModalCloseButton title={t('modal.closeModal')} onClick={onClose} />
205
- </ModalHeader>
206
- <ModalBody>
207
- <hr />
208
- <p>{t('resource.dialogText1')}</p>
209
- <p>{t('resource.dialogText2')}</p>
210
- </ModalBody>
211
- </>
212
- )}
188
+ <Modal>
189
+ <TooltipWrapper>
190
+ <Tooltip tooltip={t('resource.dialogTooltip')}>
191
+ <ModalTrigger>
192
+ <TooltipButton aria-label={t('resource.dialogTooltip')}>
193
+ <HelpIcon invertedStyle={invertedStyle} />
194
+ </TooltipButton>
195
+ </ModalTrigger>
196
+ </Tooltip>
197
+ </TooltipWrapper>
198
+ <ModalContent>
199
+ <ModalHeader>
200
+ <ModalTitle>{t('resource.dialogHeading')}</ModalTitle>
201
+ <ModalCloseButton />
202
+ </ModalHeader>
203
+ <ModalBody>
204
+ <hr />
205
+ <p>{t('resource.dialogText1')}</p>
206
+ <p>{t('resource.dialogText2')}</p>
207
+ </ModalBody>
208
+ </ModalContent>
213
209
  </Modal>
214
210
  </StyledRow>
215
211
  )}
@@ -6,7 +6,7 @@
6
6
  *
7
7
  */
8
8
 
9
- import React from 'react';
9
+ import React, { forwardRef } from 'react';
10
10
  import { spacing, spacingUnit, breakpoints, mq, misc, fonts, colors } from '@ndla/core';
11
11
  import { Search } from '@ndla/icons/common';
12
12
  import { ButtonProps, ButtonV2 } from '@ndla/button';
@@ -62,17 +62,20 @@ const StyledSpan = styled.span`
62
62
  font-weight: ${fonts.weight.normal};
63
63
  `;
64
64
 
65
- const ToggleSearchButton = ({ children, ndlaFilm, hideOnNarrowScreen, hideOnWideScreen, ...rest }: Props) => (
66
- <StyledButton
67
- ndlaFilm={ndlaFilm}
68
- hideOnNarrowScreen={hideOnNarrowScreen}
69
- hideOnWideScreen={hideOnWideScreen}
70
- type="button"
71
- {...rest}
72
- >
73
- <StyledSpan>{children}</StyledSpan>
74
- <Search />
75
- </StyledButton>
65
+ const ToggleSearchButton = forwardRef<HTMLButtonElement, Props>(
66
+ ({ children, ndlaFilm, hideOnNarrowScreen, hideOnWideScreen, ...rest }, ref) => (
67
+ <StyledButton
68
+ ndlaFilm={ndlaFilm}
69
+ hideOnNarrowScreen={hideOnNarrowScreen}
70
+ hideOnWideScreen={hideOnWideScreen}
71
+ type="button"
72
+ ref={ref}
73
+ {...rest}
74
+ >
75
+ <StyledSpan>{children}</StyledSpan>
76
+ <Search />
77
+ </StyledButton>
78
+ ),
76
79
  );
77
80
 
78
81
  export default ToggleSearchButton;
@@ -8,7 +8,7 @@
8
8
 
9
9
  import React, { useState } from 'react';
10
10
  import styled from '@emotion/styled';
11
- import { ModalCloseButton, ModalBody, Modal, ModalTitle } from '@ndla/modal';
11
+ import { ModalCloseButton, ModalBody, ModalTitle, ModalContent } from '@ndla/modal';
12
12
  import { breakpoints, mq, spacing } from '@ndla/core';
13
13
  import { ButtonV2 } from '@ndla/button';
14
14
  import { useTranslation } from 'react-i18next';
@@ -27,7 +27,7 @@ const ModalHeaderWrapper = styled.div`
27
27
  margin-bottom: ${spacing.normal};
28
28
  `;
29
29
 
30
- const ModalContent = styled.div`
30
+ const Content = styled.div`
31
31
  max-width: 1040px;
32
32
  flex-grow: 1;
33
33
  `;
@@ -69,10 +69,8 @@ export type PopupFilterProps = {
69
69
  subjectCategories?: { categories: subjectsProps['categories'] };
70
70
  subjectValues: string[];
71
71
  programmesValues: string[];
72
- onClose: () => void;
73
72
  onToggleSubject: (value: string) => void;
74
73
  onToggleProgramme: (value: string) => void;
75
- isOpen: boolean;
76
74
  };
77
75
 
78
76
  const PopupFilter = ({
@@ -82,82 +80,69 @@ const PopupFilter = ({
82
80
  programmesValues,
83
81
  onToggleSubject,
84
82
  onToggleProgramme,
85
- onClose,
86
- isOpen,
87
83
  }: PopupFilterProps) => {
88
84
  const { t } = useTranslation();
89
85
  const [selectedMenu, setSelectedMenu] = useState(MENU_ALL_SUBJECTS);
90
- const headingId = 'popupFilterHeading';
91
86
 
92
87
  return (
93
- <Modal
94
- aria-labelledby={headingId}
95
- controlled
96
- animation="subtle"
97
- animationDuration={50}
98
- onClose={onClose}
99
- isOpen={isOpen}
100
- size="full"
101
- >
102
- {() => (
103
- <ModalBody>
104
- <ModalWrapper>
105
- <ModalContent>
106
- <ModalHeaderWrapper>
107
- <ModalTitle>{t('searchPage.searchFilterMessages.filterLabel')}</ModalTitle>
108
- <ModalCloseButton onClick={() => onClose()} title={t('searchPage.close')} />
109
- </ModalHeaderWrapper>
110
- {subjectCategories && programmes && (
111
- <MainFilterButtonWrapper>
112
- <ButtonV2
113
- onClick={() => setSelectedMenu(MENU_ALL_SUBJECTS)}
114
- colorTheme={selectedMenu !== MENU_ALL_SUBJECTS ? 'lighter' : undefined}
115
- size="normal"
116
- shape="pill"
117
- >
118
- {t('frontpageMenu.allsubjects')}
119
- </ButtonV2>
120
- </MainFilterButtonWrapper>
121
- )}
122
- {programmes && (
88
+ <ModalContent animation="subtle" animationDuration={50} size="full">
89
+ <ModalBody>
90
+ <ModalWrapper>
91
+ <Content>
92
+ <ModalHeaderWrapper>
93
+ <ModalTitle>{t('searchPage.searchFilterMessages.filterLabel')}</ModalTitle>
94
+ <ModalCloseButton />
95
+ </ModalHeaderWrapper>
96
+ {subjectCategories && programmes && (
97
+ <MainFilterButtonWrapper>
123
98
  <ButtonV2
124
- onClick={() => setSelectedMenu(MENU_PROGRAMMES)}
125
- colorTheme={selectedMenu !== MENU_PROGRAMMES ? 'lighter' : undefined}
99
+ onClick={() => setSelectedMenu(MENU_ALL_SUBJECTS)}
100
+ colorTheme={selectedMenu !== MENU_ALL_SUBJECTS ? 'lighter' : undefined}
126
101
  size="normal"
127
102
  shape="pill"
128
103
  >
129
- {t('frontpageMenu.program')}
104
+ {t('frontpageMenu.allsubjects')}
130
105
  </ButtonV2>
131
- )}
132
- {selectedMenu === MENU_ALL_SUBJECTS && subjectCategories && (
133
- <FrontpageAllSubjects
134
- categories={subjectCategories.categories}
135
- selectedSubjects={subjectValues}
136
- onToggleSubject={onToggleSubject}
137
- subjectViewType="checkbox"
138
- />
139
- )}
140
- {selectedMenu === MENU_PROGRAMMES && programmes && (
141
- <StyledList>
142
- {programmes.options.map((item: ProgrammeOptionProps) => (
143
- <StyledListItem key={item.id}>
144
- <ToggleItem
145
- id={item.id}
146
- value={item.id}
147
- checked={programmesValues.includes(item.id)}
148
- label={item.name}
149
- component="div"
150
- onChange={() => onToggleProgramme(item.id)}
151
- />
152
- </StyledListItem>
153
- ))}
154
- </StyledList>
155
- )}
156
- </ModalContent>
157
- </ModalWrapper>
158
- </ModalBody>
159
- )}
160
- </Modal>
106
+ </MainFilterButtonWrapper>
107
+ )}
108
+ {programmes && (
109
+ <ButtonV2
110
+ onClick={() => setSelectedMenu(MENU_PROGRAMMES)}
111
+ colorTheme={selectedMenu !== MENU_PROGRAMMES ? 'lighter' : undefined}
112
+ size="normal"
113
+ shape="pill"
114
+ >
115
+ {t('frontpageMenu.program')}
116
+ </ButtonV2>
117
+ )}
118
+ {selectedMenu === MENU_ALL_SUBJECTS && subjectCategories && (
119
+ <FrontpageAllSubjects
120
+ categories={subjectCategories.categories}
121
+ selectedSubjects={subjectValues}
122
+ onToggleSubject={onToggleSubject}
123
+ subjectViewType="checkbox"
124
+ />
125
+ )}
126
+ {selectedMenu === MENU_PROGRAMMES && programmes && (
127
+ <StyledList>
128
+ {programmes.options.map((item: ProgrammeOptionProps) => (
129
+ <StyledListItem key={item.id}>
130
+ <ToggleItem
131
+ id={item.id}
132
+ value={item.id}
133
+ checked={programmesValues.includes(item.id)}
134
+ label={item.name}
135
+ component="div"
136
+ onChange={() => onToggleProgramme(item.id)}
137
+ />
138
+ </StyledListItem>
139
+ ))}
140
+ </StyledList>
141
+ )}
142
+ </Content>
143
+ </ModalWrapper>
144
+ </ModalBody>
145
+ </ModalContent>
161
146
  );
162
147
  };
163
148
 
@@ -10,7 +10,8 @@ import React, { ReactNode } from 'react';
10
10
  import { useTranslation } from 'react-i18next';
11
11
  import styled from '@emotion/styled';
12
12
  import { fonts, mq, breakpoints, spacing, colors } from '@ndla/core';
13
- import { ModalCloseButton } from '@ndla/modal';
13
+ import { IconButtonV2 } from '@ndla/button';
14
+ import { Cross } from '@ndla/icons/action';
14
15
 
15
16
  const Wrapper = styled.div`
16
17
  display: flex;
@@ -67,7 +68,9 @@ const SearchNotionsResult = ({ totalCount, onRemove, children }: Props) => {
67
68
  {t(`searchPage.resultType.notionsHeading`)}
68
69
  <HeadingCount>{t(`searchPage.resultType.hits`, { count: totalCount })}</HeadingCount>
69
70
  </Heading>
70
- <ModalCloseButton onClick={onRemove} title={t(`searchPage.resultType.notionsRemove`)} />
71
+ <IconButtonV2 onClick={onRemove} aria-label={t(`searchPage.resultType.notionsRemove`)}>
72
+ <Cross />
73
+ </IconButtonV2>
71
74
  </HeadingWrapper>
72
75
  {children}
73
76
  </Wrapper>
@@ -12,7 +12,7 @@ import { Additional, Core } from '@ndla/icons/common';
12
12
  import styled from '@emotion/styled';
13
13
  import { breakpoints, colors, fonts, mq, spacing } from '@ndla/core';
14
14
  import { ButtonV2 } from '@ndla/button';
15
- import { Modal, ModalCloseButton, ModalHeader, ModalTitle } from '@ndla/modal';
15
+ import { Modal, ModalCloseButton, ModalContent, ModalHeader, ModalTitle, ModalTrigger } from '@ndla/modal';
16
16
  import { useTranslation } from 'react-i18next';
17
17
 
18
18
  const BreadcrumbPath = styled.div`
@@ -34,7 +34,7 @@ const ModalButton = styled(ButtonV2)`
34
34
  }
35
35
  `;
36
36
 
37
- const ModalContent = styled.div`
37
+ const Content = styled.div`
38
38
  padding: 0 ${spacing.small} ${spacing.normal};
39
39
  ${mq.range({ from: breakpoints.tablet })} {
40
40
  padding: 0 ${spacing.large} ${spacing.normal};
@@ -83,37 +83,32 @@ const ItemContexts = ({ contexts, id, title }: ItemContextsType) => {
83
83
  <Breadcrumb breadcrumb={mainContext.breadcrumb}>
84
84
  &nbsp;
85
85
  {contexts.length > 1 && (
86
- <Modal
87
- activateButton={
86
+ <Modal>
87
+ <ModalTrigger>
88
88
  <ModalButton variant="link">
89
89
  {t('searchPage.contextModal.button', {
90
90
  count: contexts.length - 1,
91
91
  })}
92
92
  </ModalButton>
93
- }
94
- animation="subtle"
95
- animationDuration={50}
96
- >
97
- {(onClose: () => void) => (
98
- <>
99
- <ModalHeader>
100
- <ModalTitle>{t('searchPage.contextModal.heading')}</ModalTitle>
101
- <ModalCloseButton onClick={onClose} title={t('searchPage.close')} />
102
- </ModalHeader>
103
- <ModalContent>
104
- <ContextList>
105
- {contexts.map((context) => (
106
- <ContextListItem key={context.url}>
107
- <SafeLink to={context.url}>{title}</SafeLink>
108
- <Breadcrumb breadcrumb={context.breadcrumb}>
109
- {context.isAdditional ? <Additional style={iconStyle} /> : <Core style={iconStyle} />}
110
- </Breadcrumb>
111
- </ContextListItem>
112
- ))}
113
- </ContextList>
114
- </ModalContent>
115
- </>
116
- )}
93
+ </ModalTrigger>
94
+ <ModalContent animation="subtle" animationDuration={50}>
95
+ <ModalHeader>
96
+ <ModalTitle>{t('searchPage.contextModal.heading')}</ModalTitle>
97
+ <ModalCloseButton />
98
+ </ModalHeader>
99
+ <Content>
100
+ <ContextList>
101
+ {contexts.map((context) => (
102
+ <ContextListItem key={context.url}>
103
+ <SafeLink to={context.url}>{title}</SafeLink>
104
+ <Breadcrumb breadcrumb={context.breadcrumb}>
105
+ {context.isAdditional ? <Additional style={iconStyle} /> : <Core style={iconStyle} />}
106
+ </Breadcrumb>
107
+ </ContextListItem>
108
+ ))}
109
+ </ContextList>
110
+ </Content>
111
+ </ModalContent>
117
112
  </Modal>
118
113
  )}
119
114
  </Breadcrumb>
@@ -12,6 +12,7 @@ import styled from '@emotion/styled';
12
12
  import { ButtonV2 } from '@ndla/button';
13
13
  import { Plus as PlusIcon } from '@ndla/icons/action';
14
14
 
15
+ import { Modal, ModalTrigger } from '@ndla/modal';
15
16
  import PopupFilter, { PopupFilterProps } from '../PopupFilter';
16
17
  import ActiveFilters from '../ActiveFilters';
17
18
  import { FilterProps } from '../ActiveFilterContent';
@@ -101,15 +102,13 @@ const SubjectFilters = ({ filters, activeFilters, isNarrowScreen }: SubjectFilte
101
102
  setIsOpen(true);
102
103
  };
103
104
 
104
- const handleModalClose = () => {
105
- setIsOpen(false);
106
- };
107
-
108
105
  const OpenModalButton = () => (
109
- <ButtonV2 type="button" size="normal" colorTheme="greyLighter" shape="pill" onClick={handlePopupOpen}>
110
- <FilterButtonText>{t('searchPage.searchFilterMessages.noValuesButtonText')}</FilterButtonText>
111
- <PlusIcon />
112
- </ButtonV2>
106
+ <ModalTrigger>
107
+ <ButtonV2 type="button" size="normal" colorTheme="greyLighter" shape="pill">
108
+ <FilterButtonText>{t('searchPage.searchFilterMessages.noValuesButtonText')}</FilterButtonText>
109
+ <PlusIcon />
110
+ </ButtonV2>
111
+ </ModalTrigger>
113
112
  );
114
113
 
115
114
  const ActiveFiltersElement = ({ showModalButton }: { showModalButton?: boolean }) => {
@@ -126,7 +125,7 @@ const SubjectFilters = ({ filters, activeFilters, isNarrowScreen }: SubjectFilte
126
125
  };
127
126
 
128
127
  return (
129
- <>
128
+ <Modal open={isOpen} onOpenChange={setIsOpen}>
130
129
  {isNarrowScreen ? (
131
130
  <ActiveFiltersElement showModalButton />
132
131
  ) : isNarrowScreen === false ? (
@@ -140,12 +139,10 @@ const SubjectFilters = ({ filters, activeFilters, isNarrowScreen }: SubjectFilte
140
139
  subjectCategories={subjectCategories}
141
140
  subjectValues={subjectValues}
142
141
  programmesValues={programmesValues}
143
- onClose={handleModalClose}
144
142
  onToggleSubject={onToggleSubject}
145
143
  onToggleProgramme={onToggleProgramme}
146
- isOpen={isOpen}
147
144
  />
148
- </>
145
+ </Modal>
149
146
  );
150
147
  };
151
148
 
@@ -12,7 +12,7 @@ import { animations, breakpoints, colors, fonts, mq, spacing } from '@ndla/core'
12
12
 
13
13
  import parse from 'html-react-parser';
14
14
  import { ChevronDown, ChevronUp, PlayCircleFilled } from '@ndla/icons/common';
15
- import { ModalCloseButton, Modal, ModalHeader } from '@ndla/modal';
15
+ import { ModalCloseButton, ModalContent, Modal, ModalHeader, ModalTrigger } from '@ndla/modal';
16
16
  import { ButtonV2 } from '@ndla/button';
17
17
  import { CursorClick, ExpandTwoArrows } from '@ndla/icons/action';
18
18
  import { css } from '@emotion/react';
@@ -275,9 +275,8 @@ const Topic = ({
275
275
  {topic.image && (
276
276
  <TopicHeaderVisualElementWrapper>
277
277
  {topic.visualElement ? (
278
- <Modal
279
- aria-label={t('topicPage.imageModal')}
280
- activateButton={
278
+ <Modal>
279
+ <ModalTrigger>
281
280
  <VisualElementButton
282
281
  variant="stripped"
283
282
  title={topic.visualElement.type === 'image' ? t('image.largeSize') : t('visualElement.show')}
@@ -291,19 +290,18 @@ const Topic = ({
291
290
  </ShowVisualElementWrapper>
292
291
  <ExpandVisualElementButton>{VisualElementIcon && <VisualElementIcon />}</ExpandVisualElementButton>
293
292
  </VisualElementButton>
294
- }
295
- animation="subtle"
296
- animationDuration={50}
297
- size="large"
298
- >
299
- {(onClose: () => void) => (
300
- <>
301
- <StyledModalHeader>
302
- <ModalCloseButton onClick={onClose} title={t('modal.closeModal')} />
303
- </StyledModalHeader>
304
- {topic.visualElement && topic.visualElement.element}
305
- </>
306
- )}
293
+ </ModalTrigger>
294
+ <ModalContent
295
+ aria-label={t('topicPage.imageModal')}
296
+ animation="subtle"
297
+ animationDuration={50}
298
+ size="large"
299
+ >
300
+ <StyledModalHeader>
301
+ <ModalCloseButton />
302
+ </StyledModalHeader>
303
+ {topic.visualElement && topic.visualElement.element}
304
+ </ModalContent>
307
305
  </Modal>
308
306
  ) : (
309
307
  <TopicHeaderImage