@ndla/ui 14.0.0 → 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 (189) 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/InfoBlock/InfoBlock.js +55 -0
  7. package/es/InfoBlock/index.js +1 -0
  8. package/es/MyNdla/Navigation/VerticalNavigation.js +51 -0
  9. package/es/MyNdla/Navigation/index.js +2 -0
  10. package/es/MyNdla/Resource/Folder.js +86 -0
  11. package/{lib/MyNdla/ResourceDash/ResourcesView.d.ts → es/MyNdla/Resource/index.js} +2 -3
  12. package/es/MyNdla/index.js +3 -4
  13. package/es/Resource/BlockResource.js +73 -0
  14. package/es/Resource/ListResource.js +66 -0
  15. package/es/Resource/index.js +10 -0
  16. package/es/Resource/resourceComponents.js +97 -0
  17. package/es/ResourceGroup/ResourceGroup.js +7 -5
  18. package/es/ResourceGroup/ResourceItem.js +25 -24
  19. package/es/ResourceGroup/ResourceList.js +18 -6
  20. package/es/SnackBar/SnackBar.js +117 -0
  21. package/es/SnackBar/index.js +9 -0
  22. package/es/TagSelector/SuggestionInput.js +240 -0
  23. package/es/TagSelector/Suggestions.js +93 -0
  24. package/es/TagSelector/TagSelector.js +137 -0
  25. package/es/TagSelector/index.js +9 -0
  26. package/es/TreeStructure/FolderItem.js +130 -0
  27. package/es/TreeStructure/FolderItems.js +123 -0
  28. package/es/TreeStructure/FolderNameInput.js +112 -0
  29. package/es/TreeStructure/TreeStructure.js +254 -0
  30. package/es/TreeStructure/TreeStructure.types.js +0 -0
  31. package/es/TreeStructure/TreeStructureWrapper.js +13 -0
  32. package/es/TreeStructure/helperFunctions.js +92 -0
  33. package/es/TreeStructure/index.js +9 -0
  34. package/es/TreeStructure/keyboardNavigation/keyboardNavigation.js +182 -0
  35. package/es/TreeStructure/keyboardNavigation/keyboardNavigation.types.js +0 -0
  36. package/es/all.css +72 -0
  37. package/es/index.js +8 -3
  38. package/es/locale/messages-en.js +62 -4
  39. package/es/locale/messages-nb.js +61 -3
  40. package/es/locale/messages-nn.js +61 -3
  41. package/es/locale/messages-se.js +61 -3
  42. package/es/locale/messages-sma.js +61 -3
  43. package/lib/Article/Article.d.ts +3 -1
  44. package/lib/Article/Article.js +43 -23
  45. package/lib/Article/ArticleFavoritesButton.d.ts +15 -0
  46. package/lib/Article/ArticleFavoritesButton.js +56 -0
  47. package/lib/Article/index.d.ts +2 -1
  48. package/lib/Article/index.js +8 -0
  49. package/lib/Breadcrumb/ActionBreadcrumb.d.ts +16 -0
  50. package/lib/Breadcrumb/ActionBreadcrumb.js +72 -0
  51. package/lib/Breadcrumb/index.d.ts +1 -0
  52. package/lib/Breadcrumb/index.js +8 -0
  53. package/lib/InfoBlock/InfoBlock.d.ts +8 -0
  54. package/lib/InfoBlock/InfoBlock.js +58 -0
  55. package/lib/InfoBlock/index.d.ts +1 -0
  56. package/lib/InfoBlock/index.js +13 -0
  57. package/lib/MyNdla/Navigation/VerticalNavigation.d.ts +10 -0
  58. package/lib/MyNdla/Navigation/VerticalNavigation.js +61 -0
  59. package/lib/MyNdla/Navigation/index.d.ts +2 -0
  60. package/lib/MyNdla/Navigation/index.js +15 -0
  61. package/lib/MyNdla/Resource/Folder.d.ts +20 -0
  62. package/lib/MyNdla/Resource/Folder.js +100 -0
  63. package/lib/MyNdla/Resource/index.d.ts +9 -0
  64. package/lib/MyNdla/Resource/index.js +15 -0
  65. package/lib/MyNdla/index.d.ts +3 -4
  66. package/lib/MyNdla/index.js +9 -11
  67. package/lib/Resource/BlockResource.d.ts +20 -0
  68. package/lib/Resource/BlockResource.js +84 -0
  69. package/lib/Resource/ListResource.d.ts +20 -0
  70. package/lib/Resource/ListResource.js +78 -0
  71. package/lib/Resource/index.d.ts +11 -0
  72. package/lib/Resource/index.js +29 -0
  73. package/lib/Resource/resourceComponents.d.ts +24 -0
  74. package/lib/Resource/resourceComponents.js +106 -0
  75. package/lib/ResourceGroup/ResourceGroup.d.ts +2 -1
  76. package/lib/ResourceGroup/ResourceGroup.js +7 -5
  77. package/lib/ResourceGroup/ResourceItem.d.ts +5 -1
  78. package/lib/ResourceGroup/ResourceItem.js +26 -24
  79. package/lib/ResourceGroup/ResourceList.d.ts +3 -1
  80. package/lib/ResourceGroup/ResourceList.js +18 -6
  81. package/lib/SnackBar/SnackBar.d.ts +23 -0
  82. package/lib/SnackBar/SnackBar.js +127 -0
  83. package/lib/SnackBar/index.d.ts +10 -0
  84. package/lib/SnackBar/index.js +15 -0
  85. package/lib/TagSelector/SuggestionInput.d.ts +19 -0
  86. package/lib/TagSelector/SuggestionInput.js +255 -0
  87. package/lib/TagSelector/Suggestions.d.ts +12 -0
  88. package/lib/TagSelector/Suggestions.js +96 -0
  89. package/lib/TagSelector/TagSelector.d.ts +16 -0
  90. package/lib/TagSelector/TagSelector.js +150 -0
  91. package/lib/TagSelector/index.d.ts +10 -0
  92. package/lib/TagSelector/index.js +19 -0
  93. package/lib/TreeStructure/FolderItem.d.ts +27 -0
  94. package/lib/TreeStructure/FolderItem.js +140 -0
  95. package/lib/TreeStructure/FolderItems.d.ts +11 -0
  96. package/lib/TreeStructure/FolderItems.js +130 -0
  97. package/lib/TreeStructure/FolderNameInput.d.ts +15 -0
  98. package/lib/TreeStructure/FolderNameInput.js +125 -0
  99. package/lib/TreeStructure/TreeStructure.d.ts +12 -0
  100. package/lib/TreeStructure/TreeStructure.js +273 -0
  101. package/lib/TreeStructure/TreeStructure.types.d.ts +63 -0
  102. package/lib/TreeStructure/TreeStructure.types.js +1 -0
  103. package/lib/TreeStructure/TreeStructureWrapper.d.ts +12 -0
  104. package/lib/TreeStructure/TreeStructureWrapper.js +24 -0
  105. package/lib/TreeStructure/helperFunctions.d.ts +5 -0
  106. package/lib/TreeStructure/helperFunctions.js +103 -0
  107. package/lib/TreeStructure/index.d.ts +10 -0
  108. package/lib/TreeStructure/index.js +15 -0
  109. package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.d.ts +11 -0
  110. package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.js +186 -0
  111. package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.types.d.ts +26 -0
  112. package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.types.js +1 -0
  113. package/lib/User/apiTypes.d.ts +1 -1
  114. package/lib/User/index.d.ts +2 -2
  115. package/lib/all.css +72 -0
  116. package/lib/index.d.ts +13 -4
  117. package/lib/index.js +68 -9
  118. package/lib/locale/messages-en.d.ts +58 -0
  119. package/lib/locale/messages-en.js +62 -4
  120. package/lib/locale/messages-nb.d.ts +58 -0
  121. package/lib/locale/messages-nb.js +61 -3
  122. package/lib/locale/messages-nn.d.ts +58 -0
  123. package/lib/locale/messages-nn.js +61 -3
  124. package/lib/locale/messages-se.d.ts +58 -0
  125. package/lib/locale/messages-se.js +61 -3
  126. package/lib/locale/messages-sma.d.ts +58 -0
  127. package/lib/locale/messages-sma.js +61 -3
  128. package/lib/types.d.ts +1 -1
  129. package/package.json +11 -11
  130. package/src/Article/Article.tsx +31 -0
  131. package/src/Article/ArticleFavoritesButton.tsx +40 -0
  132. package/src/Article/index.ts +2 -0
  133. package/src/Breadcrumb/ActionBreadcrumb.tsx +68 -0
  134. package/src/Breadcrumb/index.ts +2 -0
  135. package/src/InfoBlock/InfoBlock.tsx +61 -0
  136. package/src/InfoBlock/index.ts +1 -0
  137. package/src/MyNdla/Navigation/VerticalNavigation.tsx +93 -0
  138. package/src/MyNdla/Navigation/index.ts +2 -0
  139. package/src/MyNdla/Resource/Folder.tsx +143 -0
  140. package/src/MyNdla/Resource/index.ts +10 -0
  141. package/src/MyNdla/index.ts +3 -5
  142. package/src/Resource/BlockResource.tsx +101 -0
  143. package/src/Resource/ListResource.tsx +111 -0
  144. package/src/Resource/index.ts +12 -0
  145. package/src/Resource/resourceComponents.tsx +143 -0
  146. package/src/ResourceGroup/ResourceGroup.tsx +3 -0
  147. package/src/ResourceGroup/ResourceItem.tsx +17 -0
  148. package/src/ResourceGroup/ResourceList.tsx +16 -3
  149. package/src/SnackBar/SnackBar.tsx +183 -0
  150. package/src/SnackBar/index.ts +13 -0
  151. package/src/TagSelector/SuggestionInput.tsx +230 -0
  152. package/src/TagSelector/Suggestions.tsx +125 -0
  153. package/src/TagSelector/TagSelector.tsx +111 -0
  154. package/src/TagSelector/index.ts +13 -0
  155. package/src/TreeStructure/FolderItem.tsx +160 -0
  156. package/src/TreeStructure/FolderItems.tsx +109 -0
  157. package/src/TreeStructure/FolderNameInput.tsx +109 -0
  158. package/src/TreeStructure/TreeStructure.tsx +184 -0
  159. package/src/TreeStructure/TreeStructure.types.ts +69 -0
  160. package/src/TreeStructure/TreeStructureWrapper.tsx +34 -0
  161. package/src/TreeStructure/helperFunctions.ts +52 -0
  162. package/src/TreeStructure/index.ts +11 -0
  163. package/src/TreeStructure/keyboardNavigation/keyboardNavigation.ts +161 -0
  164. package/src/TreeStructure/keyboardNavigation/keyboardNavigation.types.ts +28 -0
  165. package/src/User/apiTypes.ts +1 -1
  166. package/src/User/index.ts +2 -2
  167. package/src/all.scss +1 -0
  168. package/src/index.ts +14 -5
  169. package/src/locale/messages-en.ts +56 -3
  170. package/src/locale/messages-nb.ts +55 -2
  171. package/src/locale/messages-nn.ts +55 -2
  172. package/src/locale/messages-se.ts +55 -2
  173. package/src/locale/messages-sma.ts +55 -2
  174. package/src/types.ts +1 -1
  175. package/es/MyNdla/ResourceDash/Breadcrumbs.js +0 -22
  176. package/es/MyNdla/ResourceDash/ResourceElement.js +0 -27
  177. package/es/MyNdla/ResourceDash/ResourcesView.js +0 -43
  178. package/es/MyNdla/ResourceDash/index.js +0 -4
  179. package/lib/MyNdla/ResourceDash/Breadcrumbs.d.ts +0 -15
  180. package/lib/MyNdla/ResourceDash/Breadcrumbs.js +0 -35
  181. package/lib/MyNdla/ResourceDash/ResourceElement.d.ts +0 -18
  182. package/lib/MyNdla/ResourceDash/ResourceElement.js +0 -38
  183. package/lib/MyNdla/ResourceDash/ResourcesView.js +0 -57
  184. package/lib/MyNdla/ResourceDash/index.d.ts +0 -4
  185. package/lib/MyNdla/ResourceDash/index.js +0 -31
  186. package/src/MyNdla/ResourceDash/Breadcrumbs.tsx +0 -31
  187. package/src/MyNdla/ResourceDash/ResourceElement.tsx +0 -50
  188. package/src/MyNdla/ResourceDash/ResourcesView.tsx +0 -42
  189. package/src/MyNdla/ResourceDash/index.ts +0 -5
@@ -54,14 +54,59 @@ declare const messages: {
54
54
  };
55
55
  myNdla: {
56
56
  resources: string;
57
+ resources_plural: string;
57
58
  folders: string;
59
+ folders_plural: string;
58
60
  folder: string;
59
61
  myFolders: string;
60
62
  myTags: string;
61
63
  newFolder: string;
64
+ newFolderUnder: string;
62
65
  myAccount: string;
63
66
  favourites: string;
64
67
  help: string;
68
+ more: string;
69
+ listView: string;
70
+ detailView: string;
71
+ shortView: string;
72
+ myPage: {
73
+ myPage: string;
74
+ deleteAccount: string;
75
+ logout: string;
76
+ welcome: string;
77
+ read: {
78
+ our: string;
79
+ ours: string;
80
+ };
81
+ privacy: string;
82
+ questions: {
83
+ question: string;
84
+ ask: string;
85
+ };
86
+ wishToDelete: string;
87
+ terms: string;
88
+ newFavourite: string;
89
+ feide: string;
90
+ resource: {
91
+ addToMyNdla: string;
92
+ addedToMyNdla: string;
93
+ };
94
+ storageInfo: {
95
+ title: string;
96
+ text: string;
97
+ };
98
+ folderInfo: {
99
+ title: string;
100
+ text: string;
101
+ };
102
+ tagInfo: {
103
+ title: string;
104
+ text: string;
105
+ };
106
+ };
107
+ };
108
+ snackbar: {
109
+ close: string;
65
110
  };
66
111
  labels: {
67
112
  category: string;
@@ -78,6 +123,19 @@ declare const messages: {
78
123
  contact: string;
79
124
  help: string;
80
125
  };
126
+ treeStructure: {
127
+ createFolder: string;
128
+ newFolder: {
129
+ placeholder: string;
130
+ defaultName: string;
131
+ };
132
+ };
133
+ tagSelector: {
134
+ placeholder: string;
135
+ removeTag: string;
136
+ hideAllTags: string;
137
+ showAllTags: string;
138
+ };
81
139
  htmlTitles: {
82
140
  titleTemplate: string;
83
141
  welcomePage: string;
@@ -28,6 +28,19 @@ exports.contentTypes = contentTypes;
28
28
  var titleTemplate = ' - NDLA';
29
29
 
30
30
  var messages = _objectSpread(_objectSpread({
31
+ treeStructure: {
32
+ createFolder: 'Lag mappe',
33
+ newFolder: {
34
+ placeholder: 'Skriv navn på mappe',
35
+ defaultName: 'Ny mappe'
36
+ }
37
+ },
38
+ tagSelector: {
39
+ placeholder: 'Tilknytt tag',
40
+ removeTag: 'Ta vekk tilknytning til {{name}}',
41
+ hideAllTags: 'Skjul alle tagger',
42
+ showAllTags: 'Vis alle tagger'
43
+ },
31
44
  htmlTitles: {
32
45
  titleTemplate: titleTemplate,
33
46
  welcomePage: "Forsiden".concat(titleTemplate),
@@ -927,15 +940,60 @@ var messages = _objectSpread(_objectSpread({
927
940
  close: 'Lukk faktaboks'
928
941
  },
929
942
  myNdla: {
930
- resources: 'Ressurser',
931
- folders: 'Mapper',
943
+ resources: '{{count}} ressurs',
944
+ resources_plural: '{{count}} ressurser',
945
+ folders: '{{count}} mappe',
946
+ folders_plural: '{{count}} mapper',
932
947
  folder: 'Mappe',
933
948
  myFolders: 'Mine mapper',
934
949
  myTags: 'Mine tags',
935
950
  newFolder: 'Ny mappe',
951
+ newFolderUnder: 'Lag ny mappe under {{folderName}}',
936
952
  myAccount: 'Min konto',
937
953
  favourites: 'Favoritter',
938
- help: 'Hjelp'
954
+ help: 'Hjelp',
955
+ more: 'Flere valg',
956
+ listView: 'Listevisning',
957
+ detailView: 'Detaljrik listevisning',
958
+ shortView: 'Kort visning',
959
+ myPage: {
960
+ myPage: 'Min side',
961
+ deleteAccount: 'Slett Min NDLA',
962
+ logout: 'Logg ut av Min NDLA',
963
+ welcome: 'Velkommen til Min NDLA! Nå kan du lagre dine favorittressurser fra NDLA og organisere dem slik du ønsker i mapper og med tags.',
964
+ read: {
965
+ our: 'Les våre',
966
+ ours: 'Les vår'
967
+ },
968
+ privacy: 'personvernerklæring her',
969
+ questions: {
970
+ question: 'Lurer du på noe?',
971
+ ask: 'Spør oss i chatten'
972
+ },
973
+ wishToDelete: 'Ønsker du ikke ha brukerprofil hos oss lengre?',
974
+ terms: 'vilkår for bruk',
975
+ newFavourite: 'Nylig lagt til',
976
+ feide: 'Dette henter vi om deg fra Feide',
977
+ resource: {
978
+ addToMyNdla: 'Legg i Min NDLA',
979
+ addedToMyNdla: 'Lagt i Min NDLA'
980
+ },
981
+ storageInfo: {
982
+ title: 'Slik lagrer du dine favorittressurser fra NDLA',
983
+ text: 'Når du ønsker å lagre en ressurs, kan du gjøre dette ved å klikke på hjertet øverst til høyre på siden. Du vil da få mulighet til å lagre ressursen i en mappe.'
984
+ },
985
+ folderInfo: {
986
+ title: 'Slik organiserer du dine favorittressurser i mapper',
987
+ text: 'Du kommer til mappeoversikten din ved å klikke på mine mapper i menyen til venstre. Her kan du opprette nye mapper og undermapper. Du kan også opprette en ny mappe i dialogvinduet som kommer når du klikker på et hjerte i en ressurs.'
988
+ },
989
+ tagInfo: {
990
+ title: 'Slik tagger du dine favorittressurser',
991
+ text: 'Når du lagrer en ressurs får du mulighet til å tagge ressursen med et nøkkelord. Du kan senere bruke taggene til å finne tilbake til ressurser på tvers av mapper. Ved å velge mine tagger i venstremenyen får du oversikt over alle taggene du har brukt og du kan også her se hvilke ressurser som du har tagget med det bestemte nøkkelordet.'
992
+ }
993
+ }
994
+ },
995
+ snackbar: {
996
+ close: 'Lukk melding'
939
997
  },
940
998
  labels: {
941
999
  category: 'Kategori',
package/lib/types.d.ts CHANGED
@@ -19,7 +19,7 @@ declare type ResourceTypes = {
19
19
  name: string;
20
20
  };
21
21
  export declare type Resource = {
22
- id: string | number;
22
+ id: string;
23
23
  name: string;
24
24
  contentUri?: string;
25
25
  path: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ndla/ui",
3
- "version": "14.0.0",
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.3",
40
- "@ndla/modal": "^1.2.8",
41
- "@ndla/notion": "^3.1.10",
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": "^1.0.0",
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": "79850025a1ab61d341fc5a507bed6fde7d7f4f84"
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;
@@ -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';
@@ -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 };