@ndla/ui 42.1.2 → 43.0.1

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 (121) hide show
  1. package/es/Article/ArticleNotions.js +46 -53
  2. package/es/AudioPlayer/Controls.js +41 -39
  3. package/es/Breadcrumb/index.js +0 -1
  4. package/es/Filter/FilterButtons.js +49 -53
  5. package/es/Filter/FilterListPhone.js +78 -71
  6. package/es/LanguageSelector/LanguageSelector.js +31 -36
  7. package/es/LearningPaths/LearningPathMenuModalWrapper.js +39 -28
  8. package/es/Masthead/MastheadSearchModal.js +31 -35
  9. package/es/MyNdla/Resource/Folder.js +10 -16
  10. package/es/MyNdla/index.js +1 -3
  11. package/es/NDLAFilm/AboutNdlaFilm.js +16 -20
  12. package/es/NDLAFilm/FilmMovieSearch.js +43 -11
  13. package/es/Resource/BlockResource.js +8 -11
  14. package/es/Resource/ListResource.js +8 -11
  15. package/es/Resource/resourceComponents.js +46 -35
  16. package/es/ResourcesWrapper/ResourcesTopicTitle.js +36 -44
  17. package/es/Search/ToggleSearchButton.js +7 -6
  18. package/es/SearchTypeResult/PopupFilter.js +55 -69
  19. package/es/SearchTypeResult/SearchNotionsResult.js +9 -7
  20. package/es/SearchTypeResult/components/ItemContexts.js +41 -45
  21. package/es/SearchTypeResult/components/SubjectFilters.js +16 -17
  22. package/es/Topic/Topic.js +41 -45
  23. package/es/TreeStructure/FolderItem.js +7 -11
  24. package/es/index.js +2 -2
  25. package/es/locale/messages-en.js +1 -0
  26. package/es/locale/messages-nb.js +1 -0
  27. package/es/locale/messages-nn.js +1 -0
  28. package/es/locale/messages-se.js +1 -0
  29. package/es/locale/messages-sma.js +1 -0
  30. package/lib/Article/ArticleNotions.js +45 -52
  31. package/lib/AudioPlayer/Controls.js +40 -38
  32. package/lib/Breadcrumb/index.d.ts +0 -1
  33. package/lib/Breadcrumb/index.js +0 -7
  34. package/lib/Filter/FilterButtons.js +48 -52
  35. package/lib/Filter/FilterListPhone.js +76 -69
  36. package/lib/LanguageSelector/LanguageSelector.js +31 -36
  37. package/lib/LearningPaths/LearningPathMenuModalWrapper.js +47 -35
  38. package/lib/Masthead/MastheadSearchModal.js +29 -32
  39. package/lib/MyNdla/Resource/Folder.d.ts +3 -4
  40. package/lib/MyNdla/Resource/Folder.js +10 -16
  41. package/lib/MyNdla/index.d.ts +1 -3
  42. package/lib/MyNdla/index.js +0 -14
  43. package/lib/NDLAFilm/AboutNdlaFilm.js +15 -18
  44. package/lib/NDLAFilm/FilmMovieSearch.d.ts +1 -2
  45. package/lib/NDLAFilm/FilmMovieSearch.js +46 -11
  46. package/lib/Resource/BlockResource.d.ts +3 -3
  47. package/lib/Resource/BlockResource.js +8 -11
  48. package/lib/Resource/ListResource.d.ts +3 -3
  49. package/lib/Resource/ListResource.js +8 -11
  50. package/lib/Resource/resourceComponents.js +45 -34
  51. package/lib/ResourcesWrapper/ResourcesTopicTitle.js +35 -42
  52. package/lib/Search/ToggleSearchButton.d.ts +2 -1
  53. package/lib/Search/ToggleSearchButton.js +9 -6
  54. package/lib/SearchTypeResult/PopupFilter.d.ts +1 -3
  55. package/lib/SearchTypeResult/PopupFilter.js +54 -68
  56. package/lib/SearchTypeResult/SearchNotionsResult.js +9 -7
  57. package/lib/SearchTypeResult/components/ItemContexts.js +40 -44
  58. package/lib/SearchTypeResult/components/SubjectFilters.js +16 -17
  59. package/lib/Topic/Topic.js +40 -44
  60. package/lib/TreeStructure/FolderItem.js +7 -11
  61. package/lib/index.d.ts +2 -2
  62. package/lib/index.js +0 -12
  63. package/lib/locale/messages-en.d.ts +1 -0
  64. package/lib/locale/messages-en.js +1 -0
  65. package/lib/locale/messages-nb.d.ts +1 -0
  66. package/lib/locale/messages-nb.js +1 -0
  67. package/lib/locale/messages-nn.d.ts +1 -0
  68. package/lib/locale/messages-nn.js +1 -0
  69. package/lib/locale/messages-se.d.ts +1 -0
  70. package/lib/locale/messages-se.js +1 -0
  71. package/lib/locale/messages-sma.d.ts +1 -0
  72. package/lib/locale/messages-sma.js +1 -0
  73. package/package.json +11 -12
  74. package/src/Article/ArticleNotions.tsx +29 -35
  75. package/src/AudioPlayer/Controls.tsx +22 -26
  76. package/src/Breadcrumb/index.ts +0 -2
  77. package/src/Filter/FilterButtons.tsx +28 -34
  78. package/src/Filter/FilterListPhone.tsx +63 -62
  79. package/src/LanguageSelector/LanguageSelector.tsx +26 -32
  80. package/src/LearningPaths/LearningPathMenuModalWrapper.tsx +19 -18
  81. package/src/Masthead/MastheadSearchModal.tsx +21 -29
  82. package/src/MyNdla/Resource/Folder.stories.tsx +27 -5
  83. package/src/MyNdla/Resource/Folder.tsx +4 -19
  84. package/src/MyNdla/index.ts +1 -3
  85. package/src/NDLAFilm/AboutNdlaFilm.tsx +11 -10
  86. package/src/NDLAFilm/FilmMovieSearch.tsx +32 -9
  87. package/src/Resource/BlockResource.stories.tsx +1 -1
  88. package/src/Resource/BlockResource.tsx +4 -6
  89. package/src/Resource/ListResource.tsx +4 -6
  90. package/src/Resource/Resource.stories.tsx +32 -2
  91. package/src/Resource/resourceComponents.tsx +34 -24
  92. package/src/ResourcesWrapper/ResourcesTopicTitle.tsx +23 -27
  93. package/src/Search/ToggleSearchButton.tsx +15 -12
  94. package/src/SearchTypeResult/PopupFilter.tsx +55 -70
  95. package/src/SearchTypeResult/SearchNotionsResult.tsx +5 -2
  96. package/src/SearchTypeResult/components/ItemContexts.tsx +23 -28
  97. package/src/SearchTypeResult/components/SubjectFilters.tsx +9 -12
  98. package/src/Topic/Topic.tsx +15 -17
  99. package/src/TreeStructure/FolderItem.tsx +2 -4
  100. package/src/index.ts +2 -2
  101. package/src/locale/messages-en.ts +1 -0
  102. package/src/locale/messages-nb.ts +1 -0
  103. package/src/locale/messages-nn.ts +1 -0
  104. package/src/locale/messages-se.ts +1 -0
  105. package/src/locale/messages-sma.ts +1 -0
  106. package/es/Breadcrumb/ActionBreadcrumb.js +0 -74
  107. package/es/MyNdla/Resource/FolderMenu.js +0 -74
  108. package/es/MyNdla/SettingsMenu.js +0 -98
  109. package/es/NDLAFilm/CategorySelect.js +0 -135
  110. package/lib/Breadcrumb/ActionBreadcrumb.d.ts +0 -15
  111. package/lib/Breadcrumb/ActionBreadcrumb.js +0 -82
  112. package/lib/MyNdla/Resource/FolderMenu.d.ts +0 -16
  113. package/lib/MyNdla/Resource/FolderMenu.js +0 -81
  114. package/lib/MyNdla/SettingsMenu.d.ts +0 -15
  115. package/lib/MyNdla/SettingsMenu.js +0 -102
  116. package/lib/NDLAFilm/CategorySelect.d.ts +0 -16
  117. package/lib/NDLAFilm/CategorySelect.js +0 -144
  118. package/src/Breadcrumb/ActionBreadcrumb.tsx +0 -87
  119. package/src/MyNdla/Resource/FolderMenu.tsx +0 -102
  120. package/src/MyNdla/SettingsMenu.tsx +0 -96
  121. package/src/NDLAFilm/CategorySelect.tsx +0 -197
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ndla/ui",
3
- "version": "42.1.2",
3
+ "version": "43.0.1",
4
4
  "description": "UI component library for NDLA.",
5
5
  "license": "GPL-3.0",
6
6
  "main": "lib/index.js",
@@ -31,26 +31,26 @@
31
31
  "types"
32
32
  ],
33
33
  "dependencies": {
34
- "@ndla/accordion": "^2.2.14",
34
+ "@ndla/accordion": "^2.2.16",
35
35
  "@ndla/article-scripts": "^3.0.19",
36
- "@ndla/button": "^10.2.0",
36
+ "@ndla/button": "^11.0.1",
37
37
  "@ndla/carousel": "^3.1.11",
38
38
  "@ndla/core": "^4.1.4",
39
- "@ndla/forms": "^4.3.14",
39
+ "@ndla/dropdown-menu": "^1.0.1",
40
+ "@ndla/forms": "^4.3.16",
40
41
  "@ndla/hooks": "^2.0.8",
41
42
  "@ndla/icons": "^4.0.1",
42
43
  "@ndla/licenses": "^7.1.1",
43
- "@ndla/modal": "^3.0.11",
44
- "@ndla/notion": "^5.0.12",
45
- "@ndla/safelink": "^4.1.13",
44
+ "@ndla/modal": "^4.0.0",
45
+ "@ndla/notion": "^5.0.14",
46
+ "@ndla/safelink": "^4.1.15",
47
+ "@ndla/select": "^2.4.7",
46
48
  "@ndla/switch": "^1.1.8",
47
49
  "@ndla/tabs": "^3.0.4",
48
50
  "@ndla/tooltip": "^4.1.13",
49
51
  "@ndla/util": "^3.1.14",
50
- "@radix-ui/react-dropdown-menu": "^2.0.5",
51
52
  "@radix-ui/react-popover": "^1.0.6",
52
53
  "@radix-ui/react-slider": "^1.1.2",
53
- "focus-trap-react": "^8.9.2",
54
54
  "framer-motion": "^6.5.1",
55
55
  "html-react-parser": "^3.0.8",
56
56
  "i18next-browser-languagedetector": "^6.1.1",
@@ -67,8 +67,7 @@
67
67
  "i18next": "^21.9.2",
68
68
  "lodash": "^4.17.20",
69
69
  "react": ">= 16.8.0",
70
- "react-i18next": "^11.18.6",
71
- "react-router-dom": "^6.3.0"
70
+ "react-i18next": "^11.18.6"
72
71
  },
73
72
  "devDependencies": {
74
73
  "@babel/plugin-proposal-optional-chaining": "^7.11.0",
@@ -83,5 +82,5 @@
83
82
  "publishConfig": {
84
83
  "access": "public"
85
84
  },
86
- "gitHead": "01511e002ccec48113b64d59fa4af86f39f25521"
85
+ "gitHead": "8e45543b08254be6779eacff708494896344bee8"
87
86
  }
@@ -9,7 +9,7 @@
9
9
  import React from 'react';
10
10
  import styled from '@emotion/styled';
11
11
  import { useTranslation } from 'react-i18next';
12
- import { ModalHeader, ModalCloseButton, ModalBody, Modal, ModalTitle } from '@ndla/modal';
12
+ import { ModalHeader, ModalCloseButton, ModalBody, Modal, ModalTitle, ModalTrigger, ModalContent } from '@ndla/modal';
13
13
  import { mq, breakpoints, fonts, colors } from '@ndla/core';
14
14
  import { Explanation, NotionFlip } from '@ndla/icons/common';
15
15
  import { ConceptNotion } from '../Notion';
@@ -165,48 +165,42 @@ type ArticleNotionsProps = {
165
165
  export const ArticleNotions = ({ notions, relatedContent = [], buttonOffsetRight, type }: ArticleNotionsProps) => {
166
166
  const { t } = useTranslation();
167
167
  const leftOffset = `${buttonOffsetRight - 32}px`;
168
- const headingId = 'popupNotionHeading';
169
168
 
170
169
  return (
171
170
  <ArticleNotionsContainer>
172
- <Modal
173
- aria-labelledby={headingId}
174
- activateButton={
171
+ <Modal>
172
+ <ModalTrigger>
175
173
  <NotionsTrigger role="button" aria-label={t('article.notionsPrompt')} style={{ left: leftOffset }}>
176
174
  <NotionFlip />
177
175
  <Explanation />
178
- <span id={headingId}>{t('article.notionsPrompt')}</span>
176
+ <span>{t('article.notionsPrompt')}</span>
179
177
  </NotionsTrigger>
180
- }
181
- size="large"
182
- >
183
- {(onClose: () => void) => (
184
- <div>
185
- <ModalHeader className="no-padding">
186
- <ModalHeadingContainer>
187
- <Explanation />
188
- <ModalTitle>{t('article.notionsPrompt')}</ModalTitle>
189
- </ModalHeadingContainer>
190
- <ModalCloseButton onClick={onClose} title="Lukk" />
191
- </ModalHeader>
192
- <ModalBody modifier="notions-modal-body no-padding">
193
- <NotionsContainer>
194
- {notions.map((notion) => (
195
- <ConceptNotion key={notion.id} concept={notion} type={type} />
178
+ </ModalTrigger>
179
+ <ModalContent size="large">
180
+ <ModalHeader className="no-padding">
181
+ <ModalHeadingContainer>
182
+ <Explanation />
183
+ <ModalTitle>{t('article.notionsPrompt')}</ModalTitle>
184
+ </ModalHeadingContainer>
185
+ <ModalCloseButton />
186
+ </ModalHeader>
187
+ <ModalBody modifier="notions-modal-body no-padding">
188
+ <NotionsContainer>
189
+ {notions.map((notion) => (
190
+ <ConceptNotion key={notion.id} concept={notion} type={type} />
191
+ ))}
192
+ </NotionsContainer>
193
+ {relatedContent.length > 0 && (
194
+ <RelatedContentContainer>
195
+ {relatedContent.map((content, i) => (
196
+ <li key={`notion-related-item-${i + 1}`}>
197
+ <a href={content.url}>{content.label}</a>
198
+ </li>
196
199
  ))}
197
- </NotionsContainer>
198
- {relatedContent.length > 0 && (
199
- <RelatedContentContainer>
200
- {relatedContent.map((content, i) => (
201
- <li key={`notion-related-item-${i + 1}`}>
202
- <a href={content.url}>{content.label}</a>
203
- </li>
204
- ))}
205
- </RelatedContentContainer>
206
- )}
207
- </ModalBody>
208
- </div>
209
- )}
200
+ </RelatedContentContainer>
201
+ )}
202
+ </ModalBody>
203
+ </ModalContent>
210
204
  </Modal>
211
205
  </ArticleNotionsContainer>
212
206
  );
@@ -8,14 +8,14 @@
8
8
 
9
9
  import React, { useEffect, useRef, useState } from 'react';
10
10
  import styled from '@emotion/styled';
11
- import { Root, Trigger, Item, Content, DropdownMenuPortal } from '@radix-ui/react-dropdown-menu';
12
11
  import { Root as SliderRoot, Track, Range, SliderThumb } from '@radix-ui/react-slider';
13
12
  import { Root as PopoverRoot, PopoverContent, PopoverTrigger, PopoverPortal } from '@radix-ui/react-popover';
14
13
  import { Play, Pause, VolumeUp } from '@ndla/icons/common';
15
- import { breakpoints, colors, fonts, misc, mq, spacing } from '@ndla/core';
14
+ import { breakpoints, colors, fonts, mq, spacing } from '@ndla/core';
16
15
  import { useTranslation } from 'react-i18next';
17
16
  import { Back15, Forward15 } from '@ndla/icons/action';
18
17
  import { ButtonV2, IconButtonV2 } from '@ndla/button';
18
+ import { DropdownMenu, DropdownContent, DropdownItem, DropdownTrigger } from '@ndla/dropdown-menu';
19
19
 
20
20
  const ControlsWrapper = styled.div`
21
21
  border: 1px solid ${colors.brand.lighter};
@@ -59,22 +59,15 @@ const SpeedButton = styled(ButtonV2)`
59
59
  }
60
60
  `;
61
61
 
62
- const SpeedList = styled(Content)`
63
- background: ${colors.white};
62
+ const SpeedList = styled(DropdownContent)`
64
63
  border: 1px solid ${colors.brand.lighter};
65
- border-radius: ${misc.borderRadius};
66
64
  padding: 5px 10px;
67
- display: flex;
68
- flex-direction: column;
69
65
  justify-content: center;
70
66
  `;
71
67
 
72
- const SpeedValueButton = styled(Item)`
73
- height: 28px;
68
+ const SpeedValueButton = styled(ButtonV2)`
74
69
  padding: 0 14px;
75
- cursor: pointer;
76
- font-weight: ${fonts.weight.semibold};
77
- ${fonts.sizes('14px')};
70
+ gap: 0px;
78
71
  color: ${colors.text.light};
79
72
  display: flex;
80
73
  justify-content: center;
@@ -82,14 +75,13 @@ const SpeedValueButton = styled(Item)`
82
75
  &:active,
83
76
  &:focus,
84
77
  &[data-highlighted] {
85
- background: ${colors.brand.greyLighter};
86
- border-radius: 5px;
87
78
  outline: none;
88
79
  color: ${colors.text.primary};
89
80
  }
90
81
  `;
91
82
 
92
83
  const SpeedSelectedMark = styled.span`
84
+ align-self: flex-start;
93
85
  border-radius: 50%;
94
86
  background: #d1372e;
95
87
  width: 6px;
@@ -311,9 +303,8 @@ const Controls = ({ src, title }: Props) => {
311
303
  >
312
304
  <Back15 />
313
305
  </Back15SecButton>
314
-
315
- <Root>
316
- <Trigger asChild>
306
+ <DropdownMenu>
307
+ <DropdownTrigger>
317
308
  <SpeedButton
318
309
  shape="pill"
319
310
  variant="ghost"
@@ -324,17 +315,22 @@ const Controls = ({ src, title }: Props) => {
324
315
  >
325
316
  {speedValue}x
326
317
  </SpeedButton>
327
- </Trigger>
328
- <DropdownMenuPortal>
329
- <SpeedList side="top">
330
- {speedValues.map((speed) => (
331
- <SpeedValueButton key={speed} onSelect={() => setSpeedValue(speed)}>
318
+ </DropdownTrigger>
319
+ <SpeedList side="top">
320
+ {speedValues.map((speed) => (
321
+ <DropdownItem key={speed}>
322
+ <SpeedValueButton
323
+ variant="ghost"
324
+ colorTheme="greyLighter"
325
+ size="small"
326
+ onSelect={() => setSpeedValue(speed)}
327
+ >
332
328
  {speed}x{speed === speedValue && <SpeedSelectedMark />}
333
329
  </SpeedValueButton>
334
- ))}
335
- </SpeedList>
336
- </DropdownMenuPortal>
337
- </Root>
330
+ </DropdownItem>
331
+ ))}
332
+ </SpeedList>
333
+ </DropdownMenu>
338
334
  <Forward15SecButton
339
335
  colorTheme="greyLighter"
340
336
  variant="ghost"
@@ -14,6 +14,4 @@ export { default as HeaderBreadcrumb } from './HeaderBreadcrumb';
14
14
 
15
15
  export { default as HomeBreadcrumb } from './HomeBreadcrumb';
16
16
 
17
- export { default as ActionBreadcrumb } from './ActionBreadcrumb';
18
-
19
17
  export default Breadcrumb;
@@ -11,7 +11,7 @@ import { ButtonV2 } from '@ndla/button';
11
11
  import { breakpoints, colors, fonts, mq, spacing } from '@ndla/core';
12
12
  import { useTranslation } from 'react-i18next';
13
13
  import { Cross as CrossIcon, Plus as PlusIcon } from '@ndla/icons/action';
14
- import { ModalHeader, ModalBody, ModalCloseButton, Modal } from '@ndla/modal';
14
+ import { ModalHeader, ModalBody, ModalCloseButton, Modal, ModalTrigger, ModalContent } from '@ndla/modal';
15
15
  import ToggleItem from './ToggleItem';
16
16
  import FilterCarousel from './FilterCarousel';
17
17
 
@@ -126,45 +126,39 @@ export const FilterButtons = ({ heading, items, onFilterToggle, onRemoveAllFilte
126
126
  </ButtonV2>
127
127
  </StyledButtonElementWrapper>
128
128
  ))}
129
- <Modal
130
- aria-label={t('searchPage.searchFilterMessages.resourceTypeFilter.button')}
131
- size="full"
132
- animation="subtle"
133
- activateButton={
134
- <StyledButtonElementWrapper>
129
+ <Modal aria-label={t('searchPage.searchFilterMessages.resourceTypeFilter.button')}>
130
+ <StyledButtonElementWrapper>
131
+ <ModalTrigger>
135
132
  <ButtonV2 colorTheme="light" size="normal" shape="pill">
136
133
  <StyledButtonContent>{labels.openFilter}</StyledButtonContent>
137
134
  <StyledButtonContentSelected>
138
135
  <PlusIcon />
139
136
  </StyledButtonContentSelected>
140
137
  </ButtonV2>
141
- </StyledButtonElementWrapper>
142
- }
143
- >
144
- {(onClose: () => void) => (
145
- <>
146
- <ModalHeader>
147
- <h1>{heading}</h1>
148
- <ModalCloseButton title={t('modal.closeModal')} onClick={onClose} />
149
- </ModalHeader>
150
- <ModalBody modifier="slide-in-left">
151
- <StyledList>
152
- {items.map((item: ItemProps) => (
153
- <StyledListItem key={item.value}>
154
- <ToggleItem
155
- id={item.value}
156
- value={item.value}
157
- checked={item.selected}
158
- label={item.label}
159
- component="div"
160
- onChange={() => onFilterToggle(item.value)}
161
- />
162
- </StyledListItem>
163
- ))}
164
- </StyledList>
165
- </ModalBody>
166
- </>
167
- )}
138
+ </ModalTrigger>
139
+ </StyledButtonElementWrapper>
140
+ <ModalContent size="full" animation="subtle">
141
+ <ModalHeader>
142
+ <h1>{heading}</h1>
143
+ <ModalCloseButton />
144
+ </ModalHeader>
145
+ <ModalBody modifier="slide-in-left">
146
+ <StyledList>
147
+ {items.map((item: ItemProps) => (
148
+ <StyledListItem key={item.value}>
149
+ <ToggleItem
150
+ id={item.value}
151
+ value={item.value}
152
+ checked={item.selected}
153
+ label={item.label}
154
+ component="div"
155
+ onChange={() => onFilterToggle(item.value)}
156
+ />
157
+ </StyledListItem>
158
+ ))}
159
+ </StyledList>
160
+ </ModalBody>
161
+ </ModalContent>
168
162
  </Modal>
169
163
  </StyledButtonsWrapper>
170
164
  )}
@@ -6,9 +6,9 @@
6
6
  * FRI OG BEGRENSET
7
7
  */
8
8
 
9
- import React, { ChangeEvent, useEffect, useState } from 'react';
9
+ import React, { ChangeEvent, useCallback, useEffect, useState } from 'react';
10
10
  import { ChevronDown, ChevronUp } from '@ndla/icons/common';
11
- import { ModalHeader, ModalBody, ModalCloseButton, Modal } from '@ndla/modal';
11
+ import { ModalHeader, ModalBody, ModalCloseButton, Modal, ModalTrigger, ModalContent } from '@ndla/modal';
12
12
  import { ButtonV2 } from '@ndla/button';
13
13
  import debounce from 'lodash/debounce';
14
14
  import { classes } from './filterClasses';
@@ -69,6 +69,7 @@ const FilterListPhone = ({
69
69
  isGroupedOptions,
70
70
  showActiveFiltersOnSmallScreen,
71
71
  }: Props) => {
72
+ const [open, setOpen] = useState(false);
72
73
  const [isNarrowScreen, setIsNarrowScreen] = useState(false);
73
74
  const [visibleCount, setVisibleCount] = useState(defaultVisibleCount);
74
75
 
@@ -93,6 +94,10 @@ const FilterListPhone = ({
93
94
  /* eslint react/no-did-mount-set-state: 1 */
94
95
  };
95
96
 
97
+ const onClose = useCallback(() => {
98
+ setOpen(false);
99
+ }, []);
100
+
96
101
  const handleChange = (event: ChangeEvent<HTMLInputElement>, option: Option) => {
97
102
  let newValues = null;
98
103
  if (event.currentTarget.checked) {
@@ -137,74 +142,70 @@ const FilterListPhone = ({
137
142
  }}
138
143
  />
139
144
  )}
140
- <Modal
141
- size="full"
142
- activateButton={
145
+ <Modal open={open} onOpenChange={setOpen}>
146
+ <ModalTrigger>
143
147
  <ButtonV2 variant="outline" {...classes('modal-button')}>
144
148
  {messages.openFilter}
145
149
  </ButtonV2>
146
- }
147
- >
148
- {(onClose) => (
149
- <>
150
- <ModalHeader>
151
- <div {...classes('modal-header')}>
152
- <div {...classes('modal-heading')}>
153
- {!isNarrowScreen && label && <h1 {...classes('label')}>{label}</h1>}
154
- <ButtonV2 variant="outline" onClick={onClose}>
155
- {messages.useFilter}
156
- </ButtonV2>
157
- </div>
158
- <ModalCloseButton title={messages.closeFilter} onClick={onClose} />
150
+ </ModalTrigger>
151
+ <ModalContent size="full">
152
+ <ModalHeader>
153
+ <div {...classes('modal-header')}>
154
+ <div {...classes('modal-heading')}>
155
+ {!isNarrowScreen && label && <h1 {...classes('label')}>{label}</h1>}
156
+ <ButtonV2 variant="outline" onClick={onClose}>
157
+ {messages.useFilter}
158
+ </ButtonV2>
159
159
  </div>
160
- </ModalHeader>
161
- <ModalBody modifier="no-side-padding-mobile">
162
- {isNarrowScreen && label && <h1 {...classes('label')}>{label}</h1>}
163
- {groupedOptions.map((options, index) => (
164
- <ul
165
- key={index}
166
- {...classes('item-wrapper', {
167
- 'aligned-grouping': !!alignedGroup,
168
- 'collapse-mobile': !!collapseMobile,
169
- 'grouped-options': !!isGroupedOptions,
170
- })}
171
- >
172
- {options.map((option) => {
173
- const itemModifiers = [];
160
+ <ModalCloseButton title={messages.closeFilter} />
161
+ </div>
162
+ </ModalHeader>
163
+ <ModalBody modifier="no-side-padding-mobile">
164
+ {isNarrowScreen && label && <h1 {...classes('label')}>{label}</h1>}
165
+ {groupedOptions.map((options, index) => (
166
+ <ul
167
+ key={index}
168
+ {...classes('item-wrapper', {
169
+ 'aligned-grouping': !!alignedGroup,
170
+ 'collapse-mobile': !!collapseMobile,
171
+ 'grouped-options': !!isGroupedOptions,
172
+ })}
173
+ >
174
+ {options.map((option) => {
175
+ const itemModifiers = [];
174
176
 
175
- const checked = values.some((value) => value === option.value);
177
+ const checked = values.some((value) => value === option.value);
176
178
 
177
- if (option.noResults) {
178
- itemModifiers.push('no-results');
179
- }
179
+ if (option.noResults) {
180
+ itemModifiers.push('no-results');
181
+ }
180
182
 
181
- if (option.disabled) {
182
- itemModifiers.push('disabled');
183
- }
184
- return (
185
- <ToggleItem
186
- key={option.value}
187
- id={preid + option.value}
188
- value={option.value}
189
- checked={checked}
190
- onChange={(event) => handleChange(event, option)}
191
- label={option.title}
192
- disabled={option.disabled}
193
- modifiers={itemModifiers}
194
- />
195
- );
196
- })}
197
- </ul>
198
- ))}
183
+ if (option.disabled) {
184
+ itemModifiers.push('disabled');
185
+ }
186
+ return (
187
+ <ToggleItem
188
+ key={option.value}
189
+ id={preid + option.value}
190
+ value={option.value}
191
+ checked={checked}
192
+ onChange={(event) => handleChange(event, option)}
193
+ label={option.title}
194
+ disabled={option.disabled}
195
+ modifiers={itemModifiers}
196
+ />
197
+ );
198
+ })}
199
+ </ul>
200
+ ))}
199
201
 
200
- <div {...classes('usefilter-wrapper')}>
201
- <ButtonV2 variant="outline" onClick={onClose}>
202
- {messages.useFilter}
203
- </ButtonV2>
204
- </div>
205
- </ModalBody>
206
- </>
207
- )}
202
+ <div {...classes('usefilter-wrapper')}>
203
+ <ButtonV2 variant="outline" onClick={onClose}>
204
+ {messages.useFilter}
205
+ </ButtonV2>
206
+ </div>
207
+ </ModalBody>
208
+ </ModalContent>
208
209
  </Modal>
209
210
  </div>
210
211
  );
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  import React from 'react';
10
- import { Root, Trigger, Item, Content, Portal, Arrow } from '@radix-ui/react-dropdown-menu';
10
+ import { DropdownMenu, DropdownTrigger, DropdownContent, DropdownItem } from '@ndla/dropdown-menu';
11
11
  import { ButtonV2 } from '@ndla/button';
12
12
  import { useTranslation } from 'react-i18next';
13
13
  import { ChevronDown } from '@ndla/icons/common';
@@ -20,15 +20,12 @@ interface Props<T extends string> {
20
20
  inverted?: boolean;
21
21
  }
22
22
 
23
- const PopoverContent = styled(Content)`
24
- z-index: 9999;
25
- display: flex;
26
- flex-direction: column;
27
- overflow: hidden;
28
- background-color: ${colors.white};
23
+ const StyledDropdownContent = styled(DropdownContent)`
29
24
  border-radius: ${spacing.small};
30
25
  border: 1px solid ${colors.brand.tertiary};
31
- fill: ${colors.brand.tertiary};
26
+ [data-arrow] {
27
+ fill: ${colors.brand.tertiary};
28
+ }
32
29
  `;
33
30
 
34
31
  const LanguageChoice = styled(ButtonV2)`
@@ -67,33 +64,30 @@ const Text = styled.span`
67
64
  const LanguageSelector = <T extends string>({ locales, onSelect, inverted }: Props<T>) => {
68
65
  const { t, i18n } = useTranslation();
69
66
  return (
70
- <Root>
71
- <Trigger asChild>
67
+ <DropdownMenu>
68
+ <DropdownTrigger>
72
69
  <ButtonV2 variant="outline" shape="pill" inverted={inverted} aria-label={t('footer.selectLanguage')}>
73
70
  {t(`languages.prefixChangeLanguage`)} <ChevronDown />
74
71
  </ButtonV2>
75
- </Trigger>
76
- <Portal>
77
- <PopoverContent sideOffset={4}>
78
- <Arrow aria-hidden />
79
- {locales.map((locale) => (
80
- <Item asChild key={locale}>
81
- <LanguageChoice
82
- role="link"
83
- aria-current={i18n.language === locale}
84
- variant="ghost"
85
- shape="sharp"
86
- aria-label={t(`changeLanguage.${locale}`)}
87
- onClick={() => onSelect(locale)}
88
- >
89
- <ActivityIndicator>{i18n.language === locale && <ActiveIndicator />}</ActivityIndicator>
90
- <Text>{t(`languages.${locale}`)}</Text>
91
- </LanguageChoice>
92
- </Item>
93
- ))}
94
- </PopoverContent>
95
- </Portal>
96
- </Root>
72
+ </DropdownTrigger>
73
+ <StyledDropdownContent sideOffset={4} showArrow>
74
+ {locales.map((locale) => (
75
+ <DropdownItem key={locale}>
76
+ <LanguageChoice
77
+ role="link"
78
+ aria-current={i18n.language === locale}
79
+ variant="ghost"
80
+ shape="sharp"
81
+ aria-label={t(`changeLanguage.${locale}`)}
82
+ onClick={() => onSelect(locale)}
83
+ >
84
+ <ActivityIndicator>{i18n.language === locale && <ActiveIndicator />}</ActivityIndicator>
85
+ <Text>{t(`languages.${locale}`)}</Text>
86
+ </LanguageChoice>
87
+ </DropdownItem>
88
+ ))}
89
+ </StyledDropdownContent>
90
+ </DropdownMenu>
97
91
  );
98
92
  };
99
93
 
@@ -6,9 +6,9 @@
6
6
  *
7
7
  */
8
8
 
9
- import React, { ReactNode } from 'react';
9
+ import React, { ReactNode, useCallback, useState } from 'react';
10
10
  import { spacing, mq, breakpoints, colors } from '@ndla/core';
11
- import { ModalHeader, ModalBody, ModalCloseButton, Modal } from '@ndla/modal';
11
+ import { ModalHeader, ModalBody, ModalTrigger, ModalCloseButton, Modal, ModalContent } from '@ndla/modal';
12
12
  import { css } from '@emotion/react';
13
13
  import { ButtonV2 } from '@ndla/button';
14
14
  import { LearningPath } from '@ndla/icons/contentType';
@@ -30,7 +30,7 @@ const buttonToggleCss = css`
30
30
  }
31
31
  `;
32
32
 
33
- const StyledModal = styled(Modal)`
33
+ const StyledModalContent = styled(ModalContent)`
34
34
  background-color: ${colors.brand.greyLightest};
35
35
  `;
36
36
 
@@ -40,28 +40,29 @@ type ModalWrapperProps = {
40
40
  };
41
41
 
42
42
  const ModalWrapperComponent = ({ innerWidth, children }: ModalWrapperProps) => {
43
+ const [open, setIsOpen] = useState(false);
43
44
  const { t } = useTranslation();
45
+
46
+ const onClose = useCallback(() => {
47
+ setIsOpen(false);
48
+ }, []);
49
+
44
50
  if (innerWidth < 601) {
45
51
  return (
46
- <StyledModal
47
- animationDuration={200}
48
- size="full"
49
- activateButton={
52
+ <Modal open={open} onOpenChange={setIsOpen}>
53
+ <ModalTrigger>
50
54
  <ButtonV2 css={buttonToggleCss}>
51
55
  <LearningPath />
52
56
  <span>{t('learningPath.openMenuTooltip')}</span>
53
57
  </ButtonV2>
54
- }
55
- >
56
- {(closeModal: VoidFunction) => (
57
- <>
58
- <ModalHeader>
59
- <ModalCloseButton title={t('modal.closeModal')} onClick={closeModal} />
60
- </ModalHeader>
61
- <ModalBody>{children(closeModal)}</ModalBody>
62
- </>
63
- )}
64
- </StyledModal>
58
+ </ModalTrigger>
59
+ <StyledModalContent animationDuration={200} size="full">
60
+ <ModalHeader>
61
+ <ModalCloseButton />
62
+ </ModalHeader>
63
+ <ModalBody>{children(onClose)}</ModalBody>
64
+ </StyledModalContent>
65
+ </Modal>
65
66
  );
66
67
  }
67
68
  return <>{children(() => {})}</>;