@ndla/ui 13.2.1 → 15.0.0

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 (245) hide show
  1. package/es/Article/Article.js +22 -3
  2. package/es/Article/ArticleFavoritesButton.js +38 -0
  3. package/es/Article/index.js +2 -1
  4. package/es/Breadcrumb/ActionBreadcrumb.js +57 -0
  5. package/es/Breadcrumb/index.js +1 -0
  6. package/es/Footer/FooterAuth.js +15 -22
  7. package/es/InfoBlock/InfoBlock.js +55 -0
  8. package/es/InfoBlock/index.js +1 -0
  9. package/es/LearningPaths/LearningPathMenu.js +3 -4
  10. package/es/Masthead/MastheadAuthModal.js +2 -2
  11. package/es/MyNdla/Navigation/VerticalNavigation.js +51 -0
  12. package/es/MyNdla/Navigation/index.js +2 -0
  13. package/es/MyNdla/Resource/Folder.js +86 -0
  14. package/{lib/MyNdla/ResourceDash/ResourcesView.d.ts → es/MyNdla/Resource/index.js} +2 -3
  15. package/es/MyNdla/index.js +3 -4
  16. package/es/Notion/ConceptNotion.js +2 -1
  17. package/es/Notion/FigureNotion.js +13 -9
  18. package/es/Notion/NotionVisualElement.js +3 -2
  19. package/es/Resource/BlockResource.js +73 -0
  20. package/es/Resource/ListResource.js +66 -0
  21. package/es/Resource/index.js +10 -0
  22. package/es/Resource/resourceComponents.js +97 -0
  23. package/es/ResourceGroup/ResourceGroup.js +7 -5
  24. package/es/ResourceGroup/ResourceItem.js +28 -30
  25. package/es/ResourceGroup/ResourceList.js +18 -6
  26. package/es/Search/ActiveFilters.js +6 -7
  27. package/es/Search/ContentTypeResult.js +6 -8
  28. package/es/SearchTypeResult/ActiveFilters.js +6 -10
  29. package/es/SearchTypeResult/SearchViewType.js +5 -5
  30. package/es/SnackBar/SnackBar.js +117 -0
  31. package/es/SnackBar/index.js +9 -0
  32. package/es/TagSelector/SuggestionInput.js +240 -0
  33. package/es/TagSelector/Suggestions.js +93 -0
  34. package/es/TagSelector/TagSelector.js +137 -0
  35. package/es/TagSelector/index.js +9 -0
  36. package/es/TopicIntroductionList/TopicIntroduction.js +2 -4
  37. package/es/TopicIntroductionList/TopicShortcutItem.js +1 -3
  38. package/es/TreeStructure/FolderItem.js +130 -0
  39. package/es/TreeStructure/FolderItems.js +123 -0
  40. package/es/TreeStructure/FolderNameInput.js +112 -0
  41. package/es/TreeStructure/TreeStructure.js +254 -0
  42. package/es/TreeStructure/TreeStructure.types.js +0 -0
  43. package/es/TreeStructure/TreeStructureWrapper.js +13 -0
  44. package/es/TreeStructure/helperFunctions.js +92 -0
  45. package/es/TreeStructure/index.js +9 -0
  46. package/es/TreeStructure/keyboardNavigation/keyboardNavigation.js +182 -0
  47. package/es/TreeStructure/keyboardNavigation/keyboardNavigation.types.js +0 -0
  48. package/es/User/AuthModal.js +15 -24
  49. package/es/User/UserInfo.js +70 -0
  50. package/es/User/apiTypes.js +0 -0
  51. package/es/User/index.js +2 -0
  52. package/es/User/parseUserObject.js +102 -0
  53. package/es/all.css +90 -0
  54. package/es/index.js +9 -3
  55. package/es/locale/messages-en.js +75 -8
  56. package/es/locale/messages-nb.js +74 -7
  57. package/es/locale/messages-nn.js +74 -7
  58. package/es/locale/messages-se.js +74 -7
  59. package/es/locale/messages-sma.js +74 -7
  60. package/lib/Article/Article.d.ts +3 -1
  61. package/lib/Article/Article.js +43 -23
  62. package/lib/Article/ArticleFavoritesButton.d.ts +15 -0
  63. package/lib/Article/ArticleFavoritesButton.js +56 -0
  64. package/lib/Article/index.d.ts +2 -1
  65. package/lib/Article/index.js +8 -0
  66. package/lib/Breadcrumb/ActionBreadcrumb.d.ts +16 -0
  67. package/lib/Breadcrumb/ActionBreadcrumb.js +72 -0
  68. package/lib/Breadcrumb/index.d.ts +1 -0
  69. package/lib/Breadcrumb/index.js +8 -0
  70. package/lib/Footer/FooterAuth.d.ts +1 -1
  71. package/lib/Footer/FooterAuth.js +17 -17
  72. package/lib/InfoBlock/InfoBlock.d.ts +8 -0
  73. package/lib/InfoBlock/InfoBlock.js +58 -0
  74. package/lib/InfoBlock/index.d.ts +1 -0
  75. package/lib/InfoBlock/index.js +13 -0
  76. package/lib/LearningPaths/LearningPathMenu.js +3 -4
  77. package/lib/Masthead/MastheadAuthModal.d.ts +3 -3
  78. package/lib/Masthead/MastheadAuthModal.js +3 -3
  79. package/lib/MyNdla/Navigation/VerticalNavigation.d.ts +10 -0
  80. package/lib/MyNdla/Navigation/VerticalNavigation.js +61 -0
  81. package/lib/MyNdla/Navigation/index.d.ts +2 -0
  82. package/lib/MyNdla/Navigation/index.js +15 -0
  83. package/lib/MyNdla/Resource/Folder.d.ts +20 -0
  84. package/lib/MyNdla/Resource/Folder.js +100 -0
  85. package/lib/MyNdla/Resource/index.d.ts +9 -0
  86. package/lib/MyNdla/Resource/index.js +15 -0
  87. package/lib/MyNdla/index.d.ts +3 -4
  88. package/lib/MyNdla/index.js +9 -11
  89. package/lib/Notion/ConceptNotion.js +2 -1
  90. package/lib/Notion/FigureNotion.d.ts +1 -1
  91. package/lib/Notion/FigureNotion.js +12 -8
  92. package/lib/Notion/NotionVisualElement.js +3 -2
  93. package/lib/Resource/BlockResource.d.ts +20 -0
  94. package/lib/Resource/BlockResource.js +84 -0
  95. package/lib/Resource/ListResource.d.ts +20 -0
  96. package/lib/Resource/ListResource.js +78 -0
  97. package/lib/Resource/index.d.ts +11 -0
  98. package/lib/Resource/index.js +29 -0
  99. package/lib/Resource/resourceComponents.d.ts +24 -0
  100. package/lib/Resource/resourceComponents.js +106 -0
  101. package/lib/ResourceGroup/ResourceGroup.d.ts +2 -1
  102. package/lib/ResourceGroup/ResourceGroup.js +7 -5
  103. package/lib/ResourceGroup/ResourceItem.d.ts +5 -1
  104. package/lib/ResourceGroup/ResourceItem.js +29 -30
  105. package/lib/ResourceGroup/ResourceList.d.ts +3 -1
  106. package/lib/ResourceGroup/ResourceList.js +18 -6
  107. package/lib/Search/ActiveFilters.js +6 -7
  108. package/lib/Search/ContentTypeResult.js +6 -8
  109. package/lib/SearchTypeResult/ActiveFilters.js +6 -10
  110. package/lib/SearchTypeResult/SearchViewType.js +5 -5
  111. package/lib/SnackBar/SnackBar.d.ts +23 -0
  112. package/lib/SnackBar/SnackBar.js +127 -0
  113. package/lib/SnackBar/index.d.ts +10 -0
  114. package/lib/SnackBar/index.js +15 -0
  115. package/lib/TagSelector/SuggestionInput.d.ts +19 -0
  116. package/lib/TagSelector/SuggestionInput.js +255 -0
  117. package/lib/TagSelector/Suggestions.d.ts +12 -0
  118. package/lib/TagSelector/Suggestions.js +96 -0
  119. package/lib/TagSelector/TagSelector.d.ts +16 -0
  120. package/lib/TagSelector/TagSelector.js +150 -0
  121. package/lib/TagSelector/index.d.ts +10 -0
  122. package/lib/TagSelector/index.js +19 -0
  123. package/lib/TopicIntroductionList/TopicIntroduction.js +2 -4
  124. package/lib/TopicIntroductionList/TopicShortcutItem.js +1 -3
  125. package/lib/TreeStructure/FolderItem.d.ts +27 -0
  126. package/lib/TreeStructure/FolderItem.js +140 -0
  127. package/lib/TreeStructure/FolderItems.d.ts +11 -0
  128. package/lib/TreeStructure/FolderItems.js +130 -0
  129. package/lib/TreeStructure/FolderNameInput.d.ts +15 -0
  130. package/lib/TreeStructure/FolderNameInput.js +125 -0
  131. package/lib/TreeStructure/TreeStructure.d.ts +12 -0
  132. package/lib/TreeStructure/TreeStructure.js +273 -0
  133. package/lib/TreeStructure/TreeStructure.types.d.ts +63 -0
  134. package/lib/TreeStructure/TreeStructure.types.js +1 -0
  135. package/lib/TreeStructure/TreeStructureWrapper.d.ts +12 -0
  136. package/lib/TreeStructure/TreeStructureWrapper.js +24 -0
  137. package/lib/TreeStructure/helperFunctions.d.ts +5 -0
  138. package/lib/TreeStructure/helperFunctions.js +103 -0
  139. package/lib/TreeStructure/index.d.ts +10 -0
  140. package/lib/TreeStructure/index.js +15 -0
  141. package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.d.ts +11 -0
  142. package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.js +186 -0
  143. package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.types.d.ts +26 -0
  144. package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.types.js +1 -0
  145. package/lib/User/AuthModal.d.ts +3 -3
  146. package/lib/User/AuthModal.js +16 -23
  147. package/lib/User/UserInfo.d.ts +13 -0
  148. package/lib/User/UserInfo.js +84 -0
  149. package/lib/User/apiTypes.d.ts +61 -0
  150. package/lib/User/apiTypes.js +1 -0
  151. package/lib/User/index.d.ts +4 -0
  152. package/lib/User/index.js +8 -0
  153. package/lib/User/parseUserObject.d.ts +32 -0
  154. package/lib/User/parseUserObject.js +105 -0
  155. package/lib/all.css +90 -0
  156. package/lib/index.d.ts +14 -3
  157. package/lib/index.js +76 -10
  158. package/lib/locale/messages-en.d.ts +67 -0
  159. package/lib/locale/messages-en.js +75 -8
  160. package/lib/locale/messages-nb.d.ts +67 -0
  161. package/lib/locale/messages-nb.js +74 -7
  162. package/lib/locale/messages-nn.d.ts +67 -0
  163. package/lib/locale/messages-nn.js +74 -7
  164. package/lib/locale/messages-se.d.ts +67 -0
  165. package/lib/locale/messages-se.js +74 -7
  166. package/lib/locale/messages-sma.d.ts +67 -0
  167. package/lib/locale/messages-sma.js +74 -7
  168. package/lib/types.d.ts +1 -1
  169. package/package.json +11 -11
  170. package/src/Article/Article.tsx +31 -0
  171. package/src/Article/ArticleFavoritesButton.tsx +40 -0
  172. package/src/Article/index.ts +2 -0
  173. package/src/Breadcrumb/ActionBreadcrumb.tsx +68 -0
  174. package/src/Breadcrumb/index.ts +2 -0
  175. package/src/Footer/FooterAuth.tsx +7 -9
  176. package/src/InfoBlock/InfoBlock.tsx +61 -0
  177. package/src/InfoBlock/index.ts +1 -0
  178. package/src/LearningPaths/LearningPathMenu.tsx +1 -1
  179. package/src/Masthead/MastheadAuthModal.tsx +4 -5
  180. package/src/MyNdla/Navigation/VerticalNavigation.tsx +93 -0
  181. package/src/MyNdla/Navigation/index.ts +2 -0
  182. package/src/MyNdla/Resource/Folder.tsx +143 -0
  183. package/src/MyNdla/Resource/index.ts +10 -0
  184. package/src/MyNdla/index.ts +3 -5
  185. package/src/Notion/ConceptNotion.tsx +1 -0
  186. package/src/Notion/FigureNotion.tsx +12 -5
  187. package/src/Notion/NotionVisualElement.tsx +1 -1
  188. package/src/Resource/BlockResource.tsx +101 -0
  189. package/src/Resource/ListResource.tsx +111 -0
  190. package/src/Resource/index.ts +12 -0
  191. package/src/Resource/resourceComponents.tsx +143 -0
  192. package/src/ResourceGroup/ResourceGroup.tsx +3 -0
  193. package/src/ResourceGroup/ResourceItem.tsx +20 -3
  194. package/src/ResourceGroup/ResourceList.tsx +16 -3
  195. package/src/Search/ActiveFilters.jsx +0 -1
  196. package/src/Search/ContentTypeResult.tsx +8 -9
  197. package/src/SearchTypeResult/ActiveFilters.tsx +1 -3
  198. package/src/SearchTypeResult/SearchViewType.tsx +1 -1
  199. package/src/SnackBar/SnackBar.tsx +183 -0
  200. package/src/SnackBar/index.ts +13 -0
  201. package/src/TagSelector/SuggestionInput.tsx +230 -0
  202. package/src/TagSelector/Suggestions.tsx +125 -0
  203. package/src/TagSelector/TagSelector.tsx +111 -0
  204. package/src/TagSelector/index.ts +13 -0
  205. package/src/TopicIntroductionList/TopicIntroduction.tsx +2 -2
  206. package/src/TopicIntroductionList/TopicShortcutItem.tsx +1 -5
  207. package/src/TreeStructure/FolderItem.tsx +160 -0
  208. package/src/TreeStructure/FolderItems.tsx +109 -0
  209. package/src/TreeStructure/FolderNameInput.tsx +109 -0
  210. package/src/TreeStructure/TreeStructure.tsx +184 -0
  211. package/src/TreeStructure/TreeStructure.types.ts +69 -0
  212. package/src/TreeStructure/TreeStructureWrapper.tsx +34 -0
  213. package/src/TreeStructure/helperFunctions.ts +52 -0
  214. package/src/TreeStructure/index.ts +11 -0
  215. package/src/TreeStructure/keyboardNavigation/keyboardNavigation.ts +161 -0
  216. package/src/TreeStructure/keyboardNavigation/keyboardNavigation.types.ts +28 -0
  217. package/src/User/AuthModal.tsx +5 -26
  218. package/src/User/UserInfo.tsx +80 -0
  219. package/src/User/__tests__/parseUserObject-test.ts +315 -0
  220. package/src/User/apiTypes.ts +74 -0
  221. package/src/User/index.ts +4 -0
  222. package/src/User/parseUserObject.ts +83 -0
  223. package/src/all.scss +2 -0
  224. package/src/index.ts +15 -4
  225. package/src/locale/messages-en.ts +69 -7
  226. package/src/locale/messages-nb.ts +68 -6
  227. package/src/locale/messages-nn.ts +68 -6
  228. package/src/locale/messages-se.ts +68 -6
  229. package/src/locale/messages-sma.ts +68 -6
  230. package/src/types.ts +1 -1
  231. package/es/MyNdla/ResourceDash/Breadcrumbs.js +0 -22
  232. package/es/MyNdla/ResourceDash/ResourceElement.js +0 -27
  233. package/es/MyNdla/ResourceDash/ResourcesView.js +0 -43
  234. package/es/MyNdla/ResourceDash/index.js +0 -4
  235. package/lib/MyNdla/ResourceDash/Breadcrumbs.d.ts +0 -15
  236. package/lib/MyNdla/ResourceDash/Breadcrumbs.js +0 -35
  237. package/lib/MyNdla/ResourceDash/ResourceElement.d.ts +0 -18
  238. package/lib/MyNdla/ResourceDash/ResourceElement.js +0 -38
  239. package/lib/MyNdla/ResourceDash/ResourcesView.js +0 -57
  240. package/lib/MyNdla/ResourceDash/index.d.ts +0 -4
  241. package/lib/MyNdla/ResourceDash/index.js +0 -31
  242. package/src/MyNdla/ResourceDash/Breadcrumbs.tsx +0 -31
  243. package/src/MyNdla/ResourceDash/ResourceElement.tsx +0 -50
  244. package/src/MyNdla/ResourceDash/ResourcesView.tsx +0 -42
  245. package/src/MyNdla/ResourceDash/index.ts +0 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ndla/ui",
3
- "version": "13.2.1",
3
+ "version": "15.0.0",
4
4
  "description": "UI component library for NDLA.",
5
5
  "license": "GPL-3.0",
6
6
  "main": "lib/index.js",
@@ -31,18 +31,18 @@
31
31
  "types"
32
32
  ],
33
33
  "dependencies": {
34
- "@ndla/button": "^2.2.1",
35
- "@ndla/carousel": "^1.2.7",
34
+ "@ndla/button": "^2.3.0",
35
+ "@ndla/carousel": "^1.2.8",
36
36
  "@ndla/core": "^2.1.1",
37
37
  "@ndla/hooks": "^1.1.4",
38
- "@ndla/icons": "^1.7.1",
39
- "@ndla/licenses": "^4.1.2",
40
- "@ndla/modal": "^1.2.8",
41
- "@ndla/notion": "^3.1.9",
42
- "@ndla/safelink": "^2.0.2",
38
+ "@ndla/icons": "^1.8.0",
39
+ "@ndla/licenses": "^4.1.4",
40
+ "@ndla/modal": "^1.2.9",
41
+ "@ndla/notion": "^3.1.11",
42
+ "@ndla/safelink": "^2.0.3",
43
43
  "@ndla/switch": "^0.1.5",
44
- "@ndla/tabs": "^1.1.6",
45
- "@ndla/tooltip": "^0.3.5",
44
+ "@ndla/tabs": "^1.1.7",
45
+ "@ndla/tooltip": "^2.0.0",
46
46
  "@ndla/util": "^3.0.0",
47
47
  "@reach/menu-button": "^0.16.2",
48
48
  "@reach/slider": "^0.16.0",
@@ -81,5 +81,5 @@
81
81
  "publishConfig": {
82
82
  "access": "public"
83
83
  },
84
- "gitHead": "7bfb84eed8afc1f5a1d39d384260375e31702e43"
84
+ "gitHead": "dba041a7d8ccfcb4fb60f68625e2dfde162aa6fa"
85
85
  }
@@ -14,10 +14,12 @@ import styled from '@emotion/styled';
14
14
 
15
15
  import { useIntersectionObserver } from '@ndla/hooks';
16
16
  import { resizeObserver } from '@ndla/util';
17
+ import { spacing, spacingUnit, mq, breakpoints } from '@ndla/core';
17
18
  import { Article as ArticleType, Locale } from '../types';
18
19
  import ArticleFootNotes from './ArticleFootNotes';
19
20
  import ArticleContent from './ArticleContent';
20
21
  import ArticleByline from './ArticleByline';
22
+ import ArticleFavoritesButton from './ArticleFavoritesButton';
21
23
  import LayoutItem from '../Layout';
22
24
  import ArticleHeaderWrapper from './ArticleHeaderWrapper';
23
25
  import ArticleNotions, { NotionRelatedContent } from './ArticleNotions';
@@ -97,6 +99,22 @@ const MSGboxWrapper = styled.div`
97
99
  margin-bottom: 50px;
98
100
  `;
99
101
 
102
+ const ArticleFavoritesButtonWrapper = styled.div`
103
+ display: flex;
104
+ justify-content: flex-end;
105
+ transform: translate(${spacing.xsmall}, -${spacing.normal});
106
+ height: 0;
107
+ ${mq.range({ from: breakpoints.tablet })} {
108
+ transform: translate(${spacing.normal}, -${spacing.medium});
109
+ }
110
+ ${mq.range({ from: breakpoints.tabletWide })} {
111
+ transform: translate(${spacing.large}, -${spacing.medium});
112
+ }
113
+ ${mq.range({ from: breakpoints.desktop })} {
114
+ transform: translate(${spacingUnit * 5.5}px, -${spacing.medium});
115
+ }
116
+ `;
117
+
100
118
  type Props = {
101
119
  article: ArticleType;
102
120
  icon?: ReactNode;
@@ -117,6 +135,8 @@ type Props = {
117
135
  printUrl?: string;
118
136
  notions?: { list: ConceptNotionType[]; related: NotionRelatedContent[] };
119
137
  accessMessage?: string;
138
+ isFavorite?: boolean;
139
+ onToggleAddToFavorites?: (id: string, add: boolean) => void;
120
140
  };
121
141
 
122
142
  const getArticleContent = (content: any, locale: Locale) => {
@@ -147,6 +167,8 @@ export const Article = ({
147
167
  printUrl,
148
168
  renderMarkdown,
149
169
  accessMessage,
170
+ onToggleAddToFavorites,
171
+ isFavorite,
150
172
  }: Props) => {
151
173
  const [articleRef, { entry }] = useIntersectionObserver({
152
174
  root: null,
@@ -196,6 +218,15 @@ export const Article = ({
196
218
  </MSGboxWrapper>
197
219
  )}
198
220
  <ArticleHeaderWrapper competenceGoals={competenceGoals} competenceGoalTypes={competenceGoalTypes}>
221
+ {onToggleAddToFavorites && (
222
+ <ArticleFavoritesButtonWrapper>
223
+ <ArticleFavoritesButton
224
+ articleId={id}
225
+ isFavorite={isFavorite}
226
+ onToggleAddToFavorites={onToggleAddToFavorites}
227
+ />
228
+ </ArticleFavoritesButtonWrapper>
229
+ )}
199
230
  <ArticleTitle icon={icon} label={messages.label}>
200
231
  {title}
201
232
  </ArticleTitle>
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Copyright (c) 2022-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import React from 'react';
10
+ import { IconButtonDualStates } from '@ndla/button';
11
+ import { Heart, HeartOutline } from '@ndla/icons/action';
12
+ import Tooltip from '@ndla/tooltip';
13
+ import { useTranslation } from 'react-i18next';
14
+
15
+ export interface Props {
16
+ isFavorite?: boolean;
17
+ onToggleAddToFavorites: (id: string, add: boolean) => void;
18
+ articleId: string;
19
+ }
20
+
21
+ export const ArticleFavoritesButton = ({ isFavorite, onToggleAddToFavorites, articleId }: Props) => {
22
+ const { t } = useTranslation();
23
+ const removeFromFavoritesLabel = t('myNdla.resource.addToMyNdla');
24
+ const addToFavoritesLabel = t('myNdla.resource.addedToMyNdla');
25
+ return (
26
+ <Tooltip tooltip={isFavorite ? removeFromFavoritesLabel : addToFavoritesLabel}>
27
+ <IconButtonDualStates
28
+ ariaLabelActive={addToFavoritesLabel}
29
+ ariaLabelInActive={removeFromFavoritesLabel}
30
+ activeIcon={<Heart />}
31
+ inactiveIcon={<HeartOutline />}
32
+ active={isFavorite}
33
+ size="small"
34
+ onClick={() => onToggleAddToFavorites(articleId, !isFavorite)}
35
+ />
36
+ </Tooltip>
37
+ );
38
+ };
39
+
40
+ export default ArticleFavoritesButton;
@@ -12,6 +12,7 @@ import ArticleContent from './ArticleContent';
12
12
  import ArticleFootNotes from './ArticleFootNotes';
13
13
  import ArticleHeaderWrapper from './ArticleHeaderWrapper';
14
14
  import ArticleSideBar from './ArticleSideBar';
15
+ import ArticleFavoritesButton from './ArticleFavoritesButton';
15
16
 
16
17
  export {
17
18
  ArticleByline,
@@ -22,5 +23,6 @@ export {
22
23
  ArticleTitle,
23
24
  ArticleIntroduction,
24
25
  ArticleWrapper,
26
+ ArticleFavoritesButton,
25
27
  };
26
28
  export default Article;
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Copyright (c) 2022-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import styled from '@emotion/styled';
10
+ import { colors, fonts, spacing } from '@ndla/core';
11
+ import { ChevronRight } from '@ndla/icons/common';
12
+ import SafeLink from '@ndla/safelink';
13
+ import React from 'react';
14
+ import { MenuButton } from '@ndla/button';
15
+ import { MenuItemProps } from '@ndla/button';
16
+ import Breadcrumb from './Breadcrumb';
17
+ import { IndexedBreadcrumbItem, SimpleBreadcrumbItem } from './BreadcrumbItem';
18
+
19
+ const StyledRightChevron = styled(ChevronRight)`
20
+ color: ${colors.text.primary};
21
+ margin: ${spacing.xxsmall};
22
+ height: 24px;
23
+ width: 24px;
24
+ `;
25
+
26
+ const StyledSpan = styled.span`
27
+ color: ${colors.text.primary};
28
+ font-weight: ${fonts.weight.bold};
29
+ `;
30
+
31
+ const StyledSafeLink = styled(SafeLink)`
32
+ color: ${colors.text.primary};
33
+ box-shadow: none;
34
+ font-weight: ${fonts.weight.bold};
35
+ :hover {
36
+ color: ${colors.brand.primary};
37
+ }
38
+ `;
39
+
40
+ interface Props {
41
+ items: SimpleBreadcrumbItem[];
42
+ actionItems: MenuItemProps[];
43
+ }
44
+
45
+ const ActionBreadcrumb = ({ items, actionItems }: Props) => {
46
+ const renderItem = (item: IndexedBreadcrumbItem, totalCount: number) => {
47
+ if (item.index === totalCount - 1) {
48
+ return (
49
+ <MenuButton menuItems={actionItems} size="small">
50
+ <StyledSpan>{item.name}</StyledSpan>
51
+ </MenuButton>
52
+ );
53
+ }
54
+ return <StyledSafeLink to={item.to}>{item.name}</StyledSafeLink>;
55
+ };
56
+
57
+ const renderSeparator = (item: IndexedBreadcrumbItem, totalCount: number) => {
58
+ if (item.index === totalCount - 1) {
59
+ return null;
60
+ }
61
+
62
+ return <StyledRightChevron />;
63
+ };
64
+
65
+ return <Breadcrumb items={items} renderItem={renderItem} renderSeparator={renderSeparator} />;
66
+ };
67
+
68
+ export default ActionBreadcrumb;
@@ -14,4 +14,6 @@ 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
+
17
19
  export default Breadcrumb;
@@ -6,15 +6,13 @@
6
6
  *
7
7
  */
8
8
 
9
- import React from 'react';
10
- import { useTranslation } from 'react-i18next';
11
9
  import styled from '@emotion/styled';
10
+ import Button from '@ndla/button';
12
11
  import { animations, colors, fonts, spacing } from '@ndla/core';
13
12
  import { ChevronDown, FeideText, LogIn, LogOut } from '@ndla/icons/common';
14
- import Button from '@ndla/button';
15
-
16
- import { AuthModalProps } from '../User/AuthModal';
17
- import AuthModal from '../User';
13
+ import React from 'react';
14
+ import { useTranslation } from 'react-i18next';
15
+ import AuthModal, { AuthModalProps } from '../User/AuthModal';
18
16
 
19
17
  const Wrapper = styled.div`
20
18
  display: flex;
@@ -66,7 +64,7 @@ const AuthedButton = styled(Button)`
66
64
  }
67
65
  `;
68
66
 
69
- const FooterAuth = ({ isAuthenticated, onAuthenticateClick, authorizedRole, ...rest }: AuthModalProps) => {
67
+ const FooterAuth = ({ isAuthenticated, user, onAuthenticateClick, ...rest }: AuthModalProps) => {
70
68
  const { t } = useTranslation();
71
69
  return (
72
70
  <Wrapper>
@@ -78,11 +76,11 @@ const FooterAuth = ({ isAuthenticated, onAuthenticateClick, authorizedRole, ...r
78
76
  <AuthModal
79
77
  {...rest}
80
78
  isAuthenticated={isAuthenticated}
79
+ user={user}
81
80
  onAuthenticateClick={onAuthenticateClick}
82
- authorizedRole={authorizedRole}
83
81
  activateButton={
84
82
  <AuthedButton ghostPill size="medium">
85
- {t('user.loggedInAsButton', { role: authorizedRole })}
83
+ {t('user.loggedInAsButton', { role: user?.eduPersonPrimaryAffiliation })}
86
84
  <ChevronDown />
87
85
  </AuthedButton>
88
86
  }
@@ -0,0 +1,61 @@
1
+ /*
2
+ * Copyright (c) 2022-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import React, { ReactNode } from 'react';
10
+ import styled from '@emotion/styled';
11
+ import { spacing, fonts, colors } from '@ndla/core';
12
+
13
+ const InfoBlockWrapper = styled.div`
14
+ border-bottom: 1px solid ${colors.brand.neutral7};
15
+ padding: ${spacing.small} 0;
16
+ `;
17
+
18
+ const IconWrapper = styled.div`
19
+ align-items: flex-start;
20
+ display: flex;
21
+
22
+ svg {
23
+ height: 25px;
24
+ width: 25px;
25
+ }
26
+ `;
27
+
28
+ const StyledTextWrapper = styled.div`
29
+ ${fonts.sizes(18)}
30
+ `;
31
+
32
+ const TitleWrapper = styled.div`
33
+ display: flex;
34
+
35
+ gap: ${spacing.small};
36
+ `;
37
+
38
+ const StyledTitle = styled.h2`
39
+ ${fonts.sizes('18')}
40
+ font-weight: 700;
41
+ margin: 0;
42
+ `;
43
+
44
+ interface InfoBlockProps {
45
+ icon?: ReactNode;
46
+ title?: string;
47
+ children?: ReactNode;
48
+ }
49
+ export const InfoBlock = ({ icon, title, children }: InfoBlockProps) => {
50
+ return (
51
+ <InfoBlockWrapper>
52
+ <TitleWrapper>
53
+ <IconWrapper>{icon}</IconWrapper>
54
+ <StyledTitle>{title}</StyledTitle>
55
+ </TitleWrapper>
56
+ <StyledTextWrapper>{children}</StyledTextWrapper>
57
+ </InfoBlockWrapper>
58
+ );
59
+ };
60
+
61
+ export default InfoBlock;
@@ -0,0 +1 @@
1
+ export { InfoBlock } from './InfoBlock';
@@ -123,7 +123,7 @@ const LearningPathMenu = ({
123
123
  css={css`
124
124
  padding-left: ${spacing.small};
125
125
  `}>
126
- <Tooltip align="right" tooltip={t('learningPath.openMenuTooltip')}>
126
+ <Tooltip tooltip={t('learningPath.openMenuTooltip')}>
127
127
  <StyledToggleMenubutton type="button" onClick={() => toggleOpenState(!isOpen)}>
128
128
  {!isOpen ? <ArrowExpandRight /> : <ArrowExpandLeft />}
129
129
  </StyledToggleMenubutton>
@@ -11,8 +11,7 @@ import styled from '@emotion/styled';
11
11
  import Button from '@ndla/button';
12
12
  import { Feide } from '@ndla/icons/common';
13
13
 
14
- import AuthModal from '../User';
15
- import { AuthModalProps } from '../User/AuthModal';
14
+ import AuthModal, { AuthModalProps } from '../User/AuthModal';
16
15
 
17
16
  type FeideWrapperProps = {
18
17
  inverted?: boolean;
@@ -31,11 +30,11 @@ const StyledButton = styled(Button)<FeideWrapperProps>`
31
30
  }
32
31
  `;
33
32
 
34
- type Props = {
33
+ interface Props extends AuthModalProps {
35
34
  inverted?: boolean;
36
- };
35
+ }
37
36
 
38
- const MastheadAuthModal = ({ inverted, ...rest }: Props & AuthModalProps) => {
37
+ const MastheadAuthModal = ({ inverted, ...rest }: Props) => {
39
38
  return (
40
39
  <AuthModal
41
40
  {...rest}
@@ -0,0 +1,93 @@
1
+ /*
2
+ * Copyright (c) 2022-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import React, { ReactNode } from 'react';
10
+ import styled from '@emotion/styled';
11
+ import { colors, spacing } from '@ndla/core';
12
+ import SafeLinkButton from '@ndla/safelink';
13
+ import { mq, breakpoints } from '@ndla/core';
14
+
15
+ const NavigationWrapper = styled.div`
16
+ display: flex;
17
+ justify-content: flex-start;
18
+ margin: 0;
19
+ max-width: 20vw;
20
+ border-right: 1px solid ${colors.brand.greyLighter};
21
+ height: 100%;
22
+ ${mq.range({ until: breakpoints.tabletWide })} {
23
+ display: none;
24
+ }
25
+ `;
26
+
27
+ const Navigation = styled.div`
28
+ padding: ${spacing.large};
29
+ `;
30
+
31
+ const NavigationElementText = styled.div`
32
+ color: ${colors.text.primary};
33
+ `;
34
+
35
+ const NavigationElement = styled(SafeLinkButton)`
36
+ display: flex;
37
+ align-items: center;
38
+ gap: 11px;
39
+ height: 30px;
40
+ box-shadow: none;
41
+ &:hover {
42
+ background-color: ${colors.brand.lighter};
43
+ border-radius: 5%;
44
+ svg {
45
+ fill: ${colors.brand.primary};
46
+ }
47
+ ${NavigationElementText} {
48
+ color: ${colors.brand.primary};
49
+ }
50
+ }
51
+ &:focus {
52
+ svg {
53
+ fill: ${colors.brand.primary};
54
+ }
55
+ ${NavigationElementText} {
56
+ color: ${colors.brand.primary};
57
+ }
58
+ }
59
+ `;
60
+
61
+ const IconWrapper = styled.div`
62
+ svg {
63
+ fill: ${colors.text.primary};
64
+ height: 20px;
65
+ width: 20px;
66
+ }
67
+ `;
68
+
69
+ interface NavProps {
70
+ navElements?: {
71
+ icon: ReactNode;
72
+ url: string;
73
+ name: string;
74
+ }[];
75
+ }
76
+ export const VerticalNavigation = ({ navElements }: NavProps) => {
77
+ return (
78
+ <NavigationWrapper>
79
+ <Navigation>
80
+ {navElements?.map((element) => {
81
+ return (
82
+ <NavigationElement to={element.url}>
83
+ <IconWrapper>{element.icon}</IconWrapper>
84
+ <NavigationElementText>{element.name}</NavigationElementText>
85
+ </NavigationElement>
86
+ );
87
+ })}
88
+ </Navigation>
89
+ </NavigationWrapper>
90
+ );
91
+ };
92
+
93
+ export default VerticalNavigation;
@@ -0,0 +1,2 @@
1
+ import VerticalNavigation from './VerticalNavigation';
2
+ export { VerticalNavigation };
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Copyright (c) 2022-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import styled from '@emotion/styled';
10
+ import React, { ReactNode } from 'react';
11
+ import { FolderOutlined } from '@ndla/icons/contentType';
12
+ import { FileDocumentOutline } from '@ndla/icons/common';
13
+ import { fonts, spacing, colors } from '@ndla/core';
14
+ import { css } from '@emotion/core';
15
+ import { useTranslation } from 'react-i18next';
16
+ import SafeLink from '@ndla/safelink';
17
+ import { MenuButton } from '@ndla/button';
18
+
19
+ interface FolderIconWrapperProps {
20
+ type?: LayoutType;
21
+ }
22
+
23
+ const FolderIconWrapper = styled.div<FolderIconWrapperProps>`
24
+ display: flex;
25
+ border-radius: 100%;
26
+ padding: 11px;
27
+ background-color: ${colors.brand.greyLighter};
28
+ svg {
29
+ width: 18px;
30
+ height: 18px;
31
+ }
32
+ ${(p) =>
33
+ p.type === 'block' &&
34
+ css`
35
+ background-color: transparent;
36
+ ${FolderWrapper}:hover & {
37
+ background-color: ${colors.brand.light};
38
+ transition-duration 0.5s;
39
+ }
40
+ `};
41
+ `;
42
+
43
+ const FolderTitle = styled.h2`
44
+ ${fonts.sizes(18)};
45
+ font-weight: ${fonts.weight.normal};
46
+ margin: 0;
47
+ flex: 1;
48
+
49
+ overflow: hidden;
50
+ text-overflow: ellipsis;
51
+ // Unfortunate css needed for multi-line text overflow ellipsis.
52
+ display: -webkit-box;
53
+ -webkit-line-clamp: 1;
54
+ line-clamp: 1;
55
+ -webkit-box-orient: vertical;
56
+ `;
57
+
58
+ const FolderWrapper = styled(SafeLink)`
59
+ display: flex;
60
+ align-items: center;
61
+ padding: ${spacing.small};
62
+ border: 1px solid ${colors.brand.light};
63
+ border-radius: 2px;
64
+ box-shadow: none;
65
+ text-decoration: none;
66
+ color: ${colors.brand.greyDark};
67
+ font-family: ${fonts.sans};
68
+ transition-duration: 0.2s;
69
+ gap: ${spacing.small};
70
+ &:hover {
71
+ box-shadow: 1px 1px 6px 2px rgba(9, 55, 101, 0.08);
72
+ transition-duration: 0.2s;
73
+ ${FolderTitle} {
74
+ color: ${colors.brand.primary};
75
+ text-decoration: underline;
76
+ }
77
+ }
78
+ `;
79
+
80
+ interface Props {
81
+ title: string;
82
+ subFolders?: number;
83
+ subResources?: number;
84
+ description?: string;
85
+ link: string;
86
+ type: LayoutType;
87
+ actionMenu?: ReactNode;
88
+ }
89
+
90
+ interface IconCountProps {
91
+ type: 'resource' | 'folder';
92
+ count?: number;
93
+ layoutType: LayoutType;
94
+ }
95
+
96
+ interface IconCountWrapperProps {
97
+ type: LayoutType;
98
+ }
99
+ const IconCountWrapper = styled.div<IconCountWrapperProps>`
100
+ display: flex;
101
+ align-items: center;
102
+ gap: 2px;
103
+ ${fonts.sizes(16)};
104
+ ${(p) =>
105
+ p.type === 'block' &&
106
+ css`
107
+ opacity: 0;
108
+ ${FolderWrapper}:hover & {
109
+ opacity: 1;
110
+ }
111
+ `};
112
+ `;
113
+ const IconCount = ({ type, count, layoutType }: IconCountProps) => {
114
+ const Icon = type === 'resource' ? FileDocumentOutline : FolderOutlined;
115
+ const { t } = useTranslation();
116
+ if (!count) return null;
117
+
118
+ return (
119
+ <IconCountWrapper type={layoutType}>
120
+ <Icon aria-label={t(`myNdla.${type}s`)} />
121
+ <span>{layoutType === 'block' ? count : t(`myNdla.${type}s`, { count: 3 })}</span>
122
+ </IconCountWrapper>
123
+ );
124
+ };
125
+
126
+ type LayoutType = 'list' | 'block';
127
+
128
+ const Folder = ({ link, title, subFolders, subResources, type = 'list', actionMenu }: Props) => {
129
+ const { t } = useTranslation();
130
+ return (
131
+ <FolderWrapper to={link}>
132
+ <FolderIconWrapper type={type}>
133
+ <FolderOutlined aria-label={t('myNdla.folder')} />
134
+ </FolderIconWrapper>
135
+ <FolderTitle>{title}</FolderTitle>
136
+ <IconCount layoutType={type} type={'folder'} count={subFolders} />
137
+ <IconCount layoutType={type} type={'resource'} count={subResources} />
138
+ <MenuButton size="small" />
139
+ </FolderWrapper>
140
+ );
141
+ };
142
+
143
+ export default Folder;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Copyright (c) 2022-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import Folder from './Folder';
10
+ export { Folder };
@@ -1,5 +1,3 @@
1
- import { ResourceElement } from './ResourceDash';
2
- import { ResourcesView } from './ResourceDash';
3
- import { Breadcrumbs } from './ResourceDash';
4
-
5
- export { ResourceElement, ResourcesView, Breadcrumbs };
1
+ import Folder from './Resource/Folder';
2
+ import { VerticalNavigation } from './Navigation';
3
+ export { VerticalNavigation, Folder };
@@ -74,6 +74,7 @@ const ConceptNotion = ({ concept, disableScripts, type, hideIconsAndAuthors, fig
74
74
  <FigureNotion
75
75
  resizeIframe
76
76
  id={figureId}
77
+ title={concept.title}
77
78
  figureId={visualElementId}
78
79
  copyright={concept.copyright}
79
80
  licenseString={concept.copyright?.license?.license ?? ''}