@ndla/ui 4.3.2 → 5.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 (162) hide show
  1. package/README.md +11 -11
  2. package/es/Article/Article.js +3 -7
  3. package/es/Article/ArticleByline.js +4 -4
  4. package/es/Article/ArticleNotions.js +37 -92
  5. package/es/ContentTypeBadge/ContentTypeBadge.js +10 -1
  6. package/es/FactBox/FactBox.js +36 -11
  7. package/es/Filter/FilterButtons.js +18 -17
  8. package/es/Filter/FilterCarousel.js +198 -0
  9. package/es/Masthead/Masthead.js +24 -2
  10. package/es/Notion/ConceptNotion.js +57 -0
  11. package/es/Notion/FigureNotion.js +82 -0
  12. package/es/Notion/Notion.js +122 -48
  13. package/es/Notion/NotionImage.js +47 -0
  14. package/es/Notion/NotionVisualElement.js +38 -0
  15. package/es/Notion/index.js +2 -1
  16. package/es/SearchTypeResult/ActiveFilterContent.js +17 -2
  17. package/es/SearchTypeResult/ActiveFilters.js +64 -50
  18. package/es/SearchTypeResult/PopupFilter.js +28 -125
  19. package/es/SearchTypeResult/ResultNavigation.js +41 -14
  20. package/es/SearchTypeResult/SearchFieldHeader.js +20 -41
  21. package/es/SearchTypeResult/SearchFilterContent.js +61 -0
  22. package/es/SearchTypeResult/SearchHeader.js +51 -28
  23. package/es/SearchTypeResult/SearchItem.js +64 -190
  24. package/es/SearchTypeResult/SearchItemList.js +132 -0
  25. package/es/SearchTypeResult/SearchItems.js +17 -13
  26. package/es/SearchTypeResult/SearchNotionItem.js +13 -13
  27. package/es/SearchTypeResult/SearchNotionsResult.js +16 -21
  28. package/es/SearchTypeResult/SearchTypeHeader.js +43 -26
  29. package/es/SearchTypeResult/SearchTypeResult.js +7 -5
  30. package/es/SearchTypeResult/SearchViewType.js +93 -0
  31. package/es/SearchTypeResult/components/ItemContexts.js +125 -0
  32. package/es/SearchTypeResult/components/ItemResourceHeader.js +87 -0
  33. package/es/SearchTypeResult/components/ItemTopicHeader.js +56 -0
  34. package/es/SearchTypeResult/components/SubjectFilters.js +177 -0
  35. package/es/SearchTypeResult/index.js +2 -1
  36. package/es/all.css +1 -1
  37. package/es/index.js +3 -2
  38. package/es/locale/messages-en.js +20 -5
  39. package/es/locale/messages-nb.js +21 -6
  40. package/es/locale/messages-nn.js +21 -6
  41. package/es/model/ContentType.js +2 -1
  42. package/es/shapes.js +1 -1
  43. package/lib/Article/Article.d.ts +4 -5
  44. package/lib/Article/Article.js +3 -7
  45. package/lib/Article/ArticleByline.js +4 -4
  46. package/lib/Article/ArticleNotions.d.ts +3 -8
  47. package/lib/Article/ArticleNotions.js +41 -90
  48. package/lib/ContentTypeBadge/ContentTypeBadge.d.ts +1 -0
  49. package/lib/ContentTypeBadge/ContentTypeBadge.js +14 -2
  50. package/lib/FactBox/FactBox.js +41 -8
  51. package/lib/Filter/FilterButtons.d.ts +3 -10
  52. package/lib/Filter/FilterButtons.js +19 -17
  53. package/lib/Filter/FilterCarousel.d.ts +13 -0
  54. package/lib/Filter/FilterCarousel.js +207 -0
  55. package/lib/Masthead/Masthead.js +30 -2
  56. package/lib/Notion/ConceptNotion.d.ts +25 -0
  57. package/lib/Notion/ConceptNotion.js +79 -0
  58. package/lib/Notion/FigureNotion.d.ts +23 -0
  59. package/lib/Notion/FigureNotion.js +97 -0
  60. package/lib/Notion/Notion.d.ts +24 -11
  61. package/lib/Notion/Notion.js +120 -48
  62. package/lib/Notion/NotionImage.d.ts +15 -0
  63. package/lib/Notion/NotionImage.js +63 -0
  64. package/lib/Notion/NotionVisualElement.d.ts +22 -0
  65. package/lib/Notion/NotionVisualElement.js +51 -0
  66. package/lib/Notion/index.d.ts +1 -0
  67. package/lib/Notion/index.js +8 -0
  68. package/lib/SearchTypeResult/ActiveFilterContent.js +16 -9
  69. package/lib/SearchTypeResult/ActiveFilters.d.ts +2 -1
  70. package/lib/SearchTypeResult/ActiveFilters.js +65 -50
  71. package/lib/SearchTypeResult/PopupFilter.d.ts +13 -19
  72. package/lib/SearchTypeResult/PopupFilter.js +27 -123
  73. package/lib/SearchTypeResult/ResultNavigation.d.ts +2 -2
  74. package/lib/SearchTypeResult/ResultNavigation.js +38 -14
  75. package/lib/SearchTypeResult/SearchFieldHeader.d.ts +3 -8
  76. package/lib/SearchTypeResult/SearchFieldHeader.js +18 -39
  77. package/lib/SearchTypeResult/SearchFilterContent.d.ts +16 -0
  78. package/lib/SearchTypeResult/SearchFilterContent.js +67 -0
  79. package/lib/SearchTypeResult/SearchHeader.d.ts +3 -7
  80. package/lib/SearchTypeResult/SearchHeader.js +59 -30
  81. package/lib/SearchTypeResult/SearchItem.d.ts +8 -12
  82. package/lib/SearchTypeResult/SearchItem.js +64 -187
  83. package/lib/SearchTypeResult/SearchItemList.d.ts +10 -0
  84. package/lib/SearchTypeResult/SearchItemList.js +139 -0
  85. package/lib/SearchTypeResult/SearchItems.d.ts +4 -3
  86. package/lib/SearchTypeResult/SearchItems.js +18 -13
  87. package/lib/SearchTypeResult/SearchNotionItem.js +13 -13
  88. package/lib/SearchTypeResult/SearchNotionsResult.d.ts +2 -4
  89. package/lib/SearchTypeResult/SearchNotionsResult.js +23 -23
  90. package/lib/SearchTypeResult/SearchTypeHeader.d.ts +2 -2
  91. package/lib/SearchTypeResult/SearchTypeHeader.js +40 -25
  92. package/lib/SearchTypeResult/SearchTypeResult.d.ts +7 -6
  93. package/lib/SearchTypeResult/SearchTypeResult.js +7 -5
  94. package/lib/SearchTypeResult/SearchViewType.d.ts +13 -0
  95. package/lib/SearchTypeResult/SearchViewType.js +99 -0
  96. package/lib/SearchTypeResult/components/ItemContexts.d.ts +19 -0
  97. package/lib/SearchTypeResult/components/ItemContexts.js +134 -0
  98. package/lib/SearchTypeResult/components/ItemResourceHeader.d.ts +16 -0
  99. package/lib/SearchTypeResult/components/ItemResourceHeader.js +98 -0
  100. package/lib/SearchTypeResult/components/ItemTopicHeader.d.ts +17 -0
  101. package/lib/SearchTypeResult/components/ItemTopicHeader.js +67 -0
  102. package/lib/SearchTypeResult/components/SubjectFilters.d.ts +32 -0
  103. package/lib/SearchTypeResult/components/SubjectFilters.js +192 -0
  104. package/lib/SearchTypeResult/index.d.ts +2 -1
  105. package/lib/SearchTypeResult/index.js +8 -0
  106. package/lib/all.css +1 -1
  107. package/lib/index.d.ts +2 -1
  108. package/lib/index.js +24 -1
  109. package/lib/locale/messages-en.d.ts +16 -1
  110. package/lib/locale/messages-en.js +20 -5
  111. package/lib/locale/messages-nb.d.ts +15 -0
  112. package/lib/locale/messages-nb.js +21 -6
  113. package/lib/locale/messages-nn.d.ts +16 -1
  114. package/lib/locale/messages-nn.js +21 -6
  115. package/lib/model/ContentType.d.ts +1 -0
  116. package/lib/model/ContentType.js +4 -2
  117. package/lib/shapes.js +1 -1
  118. package/lib/types.d.ts +1 -0
  119. package/package.json +14 -14
  120. package/src/Article/Article.tsx +8 -15
  121. package/src/Article/ArticleByline.tsx +1 -1
  122. package/src/Article/ArticleNotions.tsx +13 -33
  123. package/src/ContentTypeBadge/ContentTypeBadge.tsx +8 -0
  124. package/src/ContentTypeBadge/component.content-type-badge.scss +5 -0
  125. package/src/FactBox/FactBox.tsx +22 -15
  126. package/src/Figure/component.figure.scss +1 -1
  127. package/src/Filter/FilterButtons.tsx +14 -15
  128. package/src/Filter/FilterCarousel.tsx +166 -0
  129. package/src/Masthead/Masthead.tsx +42 -18
  130. package/src/Notion/ConceptNotion.tsx +80 -0
  131. package/src/Notion/FigureNotion.tsx +86 -0
  132. package/src/Notion/Notion.tsx +205 -75
  133. package/src/Notion/NotionImage.tsx +51 -0
  134. package/src/Notion/NotionVisualElement.tsx +50 -0
  135. package/src/Notion/index.ts +1 -0
  136. package/src/SearchTypeResult/ActiveFilterContent.tsx +7 -2
  137. package/src/SearchTypeResult/ActiveFilters.tsx +72 -38
  138. package/src/SearchTypeResult/PopupFilter.tsx +73 -146
  139. package/src/SearchTypeResult/ResultNavigation.tsx +54 -16
  140. package/src/SearchTypeResult/SearchFieldHeader.tsx +15 -40
  141. package/src/SearchTypeResult/SearchFilterContent.tsx +63 -0
  142. package/src/SearchTypeResult/SearchHeader.tsx +31 -31
  143. package/src/SearchTypeResult/SearchItem.tsx +145 -233
  144. package/src/SearchTypeResult/SearchItemList.tsx +167 -0
  145. package/src/SearchTypeResult/SearchItems.tsx +26 -19
  146. package/src/SearchTypeResult/SearchNotionItem.tsx +5 -12
  147. package/src/SearchTypeResult/SearchNotionsResult.tsx +29 -22
  148. package/src/SearchTypeResult/SearchTypeHeader.tsx +51 -33
  149. package/src/SearchTypeResult/SearchTypeResult.tsx +13 -12
  150. package/src/SearchTypeResult/SearchViewType.tsx +109 -0
  151. package/src/SearchTypeResult/components/ItemContexts.tsx +138 -0
  152. package/src/SearchTypeResult/components/ItemResourceHeader.tsx +133 -0
  153. package/src/SearchTypeResult/components/ItemTopicHeader.tsx +95 -0
  154. package/src/SearchTypeResult/components/SubjectFilters.tsx +152 -0
  155. package/src/SearchTypeResult/index.ts +9 -1
  156. package/src/index.ts +3 -0
  157. package/src/locale/messages-en.ts +18 -3
  158. package/src/locale/messages-nb.ts +19 -4
  159. package/src/locale/messages-nn.ts +19 -4
  160. package/src/model/ContentType.ts +1 -0
  161. package/src/shapes.js +1 -0
  162. package/src/types.ts +1 -0
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Copyright (c) 2021-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, { Fragment } from 'react';
10
+ import { useTranslation } from 'react-i18next';
11
+ import styled from '@emotion/styled';
12
+
13
+ import { animations, fonts, spacing } from '@ndla/core';
14
+
15
+ import { ContentType } from '../SearchTypeResult';
16
+ import { resourceTypeColor, SearchItemType } from '../SearchItem';
17
+ import ContentTypeBadge from '../../ContentTypeBadge';
18
+
19
+ type ItemTypeProps = {
20
+ contentType?: ContentType;
21
+ };
22
+
23
+ const ImageElement = styled.img`
24
+ border-top-left-radius: 5px;
25
+ border-top-right-radius: 5px;
26
+ width: 100%;
27
+ height: 100%;
28
+ object-fit: cover;
29
+ flex: 1;
30
+ min-height: 40px;
31
+ `;
32
+
33
+ const NoImageElement = styled.div<ItemTypeProps>`
34
+ border-top-left-radius: 5px;
35
+ border-top-right-radius: 5px;
36
+ flex: 1;
37
+ min-height: 40px;
38
+ background: ${(props) => props.contentType && `${resourceTypeColor(props.contentType)}`};
39
+ position: relative;
40
+ transition: background-color ${animations.durations.normal} ease-in-out;
41
+ .c-content-type-badge {
42
+ transition: all ${animations.durations.normal} ease-in-out;
43
+ position: absolute;
44
+ width: 58px;
45
+ height: 58px;
46
+ left: 50%;
47
+ margin-left: -29px;
48
+ top: 50%;
49
+ margin-top: -18px;
50
+ opacity: 0.2;
51
+ z-index: 3;
52
+ svg {
53
+ width: 58px;
54
+ height: 58px;
55
+ }
56
+ }
57
+ `;
58
+
59
+ const ContentTypeWrapper = styled.div<ItemTypeProps>`
60
+ height: 48px;
61
+ background: ${(props) => props.contentType && `${resourceTypeColor(props.contentType)}`};
62
+ flex: 0 0 auto;
63
+ position: relative;
64
+ display: flex;
65
+ align-items: center;
66
+ padding: 0 ${spacing.normal};
67
+ ${fonts.sizes('12px', '16px')};
68
+ font-weight: ${fonts.weight.semibold};
69
+ transition: all ${animations.durations.fast} ease-in-out;
70
+ `;
71
+
72
+ const ContentTypeIcon = styled.span<ItemTypeProps>`
73
+ position: absolute;
74
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='78' height='23' viewBox='17 0 78 23' fill='none'%3E%3Cpath d='M35.6874 10.8284C37.0999 8.9889 38.405 7.28934 40 6C44.8452 2.08335 48.9078 0 56 0C63.0922 0 67.6548 2.5833 72.5 6.49995C74.0499 7.75284 75.2937 9.39082 76.6385 11.1617C80.0028 15.5921 83.9988 20.8545 95 23H17C27.9865 20.8573 32.1701 15.409 35.6874 10.8284ZM352' fill='${(
75
+ props,
76
+ ) => props.contentType && `${encodeURIComponent(resourceTypeColor(props.contentType))}`}'/%3E%3C/svg%3E");
77
+ background-position: top;
78
+ background-repeat: no-repeat;
79
+ left: 17px;
80
+ top: -23px;
81
+ height: 45px;
82
+ width: 78px;
83
+ display: flex;
84
+ justify-content: center;
85
+ align-items: center;
86
+ transition: all ${animations.durations.fast} ease-in-out;
87
+ z-index: 2;
88
+
89
+ svg {
90
+ transition: all ${animations.durations.fast} ease-in-out;
91
+ width: 20px;
92
+ height: 20px;
93
+ }
94
+ `;
95
+
96
+ type Props = {
97
+ labels: SearchItemType['item']['labels'];
98
+ img?: SearchItemType['item']['img'] | null;
99
+ type?: ContentType;
100
+ };
101
+
102
+ const ItemResourceHeader = ({ labels = [], img, type }: Props) => {
103
+ const { t } = useTranslation();
104
+ return (
105
+ <>
106
+ {img ? (
107
+ <ImageElement src={img.url} alt={img.alt} />
108
+ ) : (
109
+ <NoImageElement className="resource-no-image" contentType={type}>
110
+ {type && <ContentTypeBadge type={type} border={false} />}
111
+ </NoImageElement>
112
+ )}
113
+ <ContentTypeWrapper className="resource-type-wrapper" contentType={type}>
114
+ <ContentTypeIcon className="resource-icon-wrapper" contentType={type}>
115
+ {img && type && <ContentTypeBadge type={type} border={false} />}
116
+ </ContentTypeIcon>
117
+ {type && t(`contentTypes.${type}`)}
118
+ {labels.length > 0 && (
119
+ <>
120
+ {labels.map((label) => (
121
+ <Fragment key={label}>
122
+ {' '}
123
+ <>&#8226;</> {label}
124
+ </Fragment>
125
+ ))}
126
+ </>
127
+ )}
128
+ </ContentTypeWrapper>
129
+ </>
130
+ );
131
+ };
132
+
133
+ export default ItemResourceHeader;
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Copyright (c) 2021-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 { useTranslation } from 'react-i18next';
11
+ import styled from '@emotion/styled';
12
+ import { animations, colors, fonts, spacing } from '@ndla/core';
13
+
14
+ import { SearchItemType } from '../SearchItem';
15
+ import ContentTypeBadge from '../../ContentTypeBadge';
16
+ import { ContentType } from '../SearchTypeResult';
17
+
18
+ const Wrapper = styled.div`
19
+ padding: ${spacing.small} ${spacing.normal};
20
+ position: relative;
21
+ min-height: 0;
22
+ flex: 1;
23
+ `;
24
+
25
+ const Label = styled.div`
26
+ ${fonts.sizes('12px', '16px')};
27
+ font-weight: ${fonts.weight.semibold};
28
+ height: 26px;
29
+ display: flex;
30
+ align-items: center;
31
+ margin-top: ${spacing.small};
32
+ transition: all ${animations.durations.fast} ease-in-out;
33
+
34
+ .c-content-type-badge {
35
+ width: 26px;
36
+ height: 26px;
37
+ margin-right: ${spacing.xsmall};
38
+ }
39
+
40
+ svg {
41
+ transition: all ${animations.durations.fast} ease-in-out;
42
+ width: 22px;
43
+ height: 22px;
44
+ color: ${colors.text.primary} !important;
45
+ }
46
+ `;
47
+
48
+ const TopicHeaderVisualElementWrapper = styled.div`
49
+ float: right;
50
+ margin-left: ${spacing.small};
51
+ position: relative;
52
+ width: 112px;
53
+ height: 112px;
54
+ display: flex;
55
+ justify-content: center;
56
+ align-items: center;
57
+ `;
58
+
59
+ const TopicHeaderImage = styled.img`
60
+ border-radius: 50%;
61
+ width: 100%;
62
+ height: 100%;
63
+ object-fit: cover;
64
+ transition: all ${animations.durations.fast} ease-in-out;
65
+ max-width: unset;
66
+ `;
67
+
68
+ type Props = {
69
+ children: ReactNode;
70
+ image?: SearchItemType['item']['img'] | null;
71
+ type?: ContentType;
72
+ };
73
+ const ItemTopicHeader = ({ children, image, type }: Props) => {
74
+ const { t } = useTranslation();
75
+ return (
76
+ <Wrapper>
77
+ {image && (
78
+ <TopicHeaderVisualElementWrapper>
79
+ <TopicHeaderImage className="topic-header-image" src={image.url} alt={image.alt} />
80
+ </TopicHeaderVisualElementWrapper>
81
+ )}
82
+ <Label className="topic-label">
83
+ {type && (
84
+ <>
85
+ <ContentTypeBadge type={type} border={false} />
86
+ {t(`contentTypes.${type}`)}
87
+ </>
88
+ )}
89
+ </Label>
90
+ {children}
91
+ </Wrapper>
92
+ );
93
+ };
94
+
95
+ export default ItemTopicHeader;
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Copyright (c) 2021-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, { useEffect, useRef, useState } from 'react';
10
+ import { useTranslation } from 'react-i18next';
11
+ import styled from '@emotion/styled';
12
+ import Button from '@ndla/button';
13
+ import { Plus as PlusIcon } from '@ndla/icons/action';
14
+
15
+ import PopupFilter, { PopupFilterProps } from '../PopupFilter';
16
+ import ActiveFilters from '../ActiveFilters';
17
+ import { FilterProps } from '../ActiveFilterContent';
18
+
19
+ const FilterButtonText = styled.span`
20
+ display: inline-block;
21
+ font-weight: 600;
22
+ margin-right: 10px;
23
+ `;
24
+
25
+ type ProgrammeProps = PopupFilterProps['programmes'] & {
26
+ values: string[];
27
+ onProgrammeValuesChange: (values: string[]) => void;
28
+ };
29
+
30
+ type SubjectCategoriesProps = PopupFilterProps['subjectCategories'] & {
31
+ values: string[];
32
+ onSubjectValuesChange: (values: string[]) => void;
33
+ };
34
+
35
+ export type SubjectFilterProps = {
36
+ filters: {
37
+ programmes?: ProgrammeProps;
38
+ subjectCategories?: SubjectCategoriesProps;
39
+ };
40
+ activeFilters?: {
41
+ filters: FilterProps[];
42
+ onFilterRemove: (value: string, name: string) => void;
43
+ };
44
+ };
45
+
46
+ type Props = {
47
+ isNarrowScreen?: boolean;
48
+ };
49
+
50
+ const SubjectFilters = ({ filters, activeFilters, isNarrowScreen }: SubjectFilterProps & Props) => {
51
+ const { t } = useTranslation();
52
+ const { subjectCategories, programmes } = filters;
53
+ const [subjectValues, setSubjectValues] = useState<Array<string>>([]);
54
+ const [programmesValues, setProgrammesValues] = useState<Array<string>>([]);
55
+ const [isOpen, setIsOpen] = useState(false);
56
+
57
+ const prevIsOpenRef = useRef<boolean>();
58
+ useEffect(() => {
59
+ prevIsOpenRef.current = isOpen;
60
+ });
61
+ const prevIsOpen = prevIsOpenRef.current;
62
+
63
+ useEffect(() => {
64
+ if (isOpen && isOpen !== prevIsOpen) {
65
+ if (subjectCategories) {
66
+ setSubjectValues([...subjectCategories.values]);
67
+ }
68
+ if (programmes) {
69
+ setProgrammesValues([...programmes.values]);
70
+ }
71
+ }
72
+ }, [isOpen, prevIsOpen, subjectCategories, programmes]);
73
+
74
+ const onToggleSubject = (subjectId: string) => {
75
+ let updatedFilter = [...subjectValues];
76
+ if (updatedFilter.includes(subjectId)) {
77
+ updatedFilter = subjectValues.filter((option) => option !== subjectId);
78
+ } else {
79
+ updatedFilter.push(subjectId);
80
+ }
81
+ setSubjectValues(updatedFilter);
82
+ if (subjectCategories) {
83
+ subjectCategories.onSubjectValuesChange(updatedFilter);
84
+ }
85
+ };
86
+
87
+ const onToggleProgramme = (programmeId: string) => {
88
+ let updatedFilter = [...programmesValues];
89
+ if (updatedFilter.includes(programmeId)) {
90
+ updatedFilter = programmesValues.filter((option) => option !== programmeId);
91
+ } else {
92
+ updatedFilter.push(programmeId);
93
+ }
94
+ setProgrammesValues(updatedFilter);
95
+ if (programmes) {
96
+ programmes.onProgrammeValuesChange(updatedFilter);
97
+ }
98
+ };
99
+
100
+ const handlePopupOpen = () => {
101
+ setIsOpen(true);
102
+ };
103
+
104
+ const handleModalClose = () => {
105
+ setIsOpen(false);
106
+ };
107
+
108
+ const OpenModalButton = () => (
109
+ <Button type="button" size="normal" greyLighter borderShape="rounded" onClick={handlePopupOpen}>
110
+ <FilterButtonText>{t('searchPage.searchFilterMessages.noValuesButtonText')}</FilterButtonText>
111
+ <PlusIcon />
112
+ </Button>
113
+ );
114
+
115
+ const ActiveFiltersElement = ({ showModalButton }: { showModalButton?: boolean }) => {
116
+ const customElements = showModalButton ? [OpenModalButton()] : [];
117
+ if (!activeFilters) return null;
118
+ return (
119
+ <ActiveFilters
120
+ {...activeFilters}
121
+ showOnSmallScreen={isNarrowScreen}
122
+ onClickShowHiddenSubjects={handlePopupOpen}
123
+ customElements={customElements}
124
+ />
125
+ );
126
+ };
127
+
128
+ return (
129
+ <>
130
+ {isNarrowScreen ? (
131
+ <ActiveFiltersElement showModalButton />
132
+ ) : isNarrowScreen === false ? (
133
+ <>
134
+ <OpenModalButton />
135
+ <ActiveFiltersElement />
136
+ </>
137
+ ) : undefined}
138
+ <PopupFilter
139
+ programmes={programmes}
140
+ subjectCategories={subjectCategories}
141
+ subjectValues={subjectValues}
142
+ programmesValues={programmesValues}
143
+ onClose={handleModalClose}
144
+ onToggleSubject={onToggleSubject}
145
+ onToggleProgramme={onToggleProgramme}
146
+ isOpen={isOpen}
147
+ />
148
+ </>
149
+ );
150
+ };
151
+
152
+ export default SubjectFilters;
@@ -11,7 +11,15 @@ import SearchHeader from './SearchHeader';
11
11
  import SearchFieldHeader from './SearchFieldHeader';
12
12
  import SearchNotionsResult from './SearchNotionsResult';
13
13
  import SearchSubjectResult from './SearchSubjectResult';
14
+ import SearchFilterContent from './SearchFilterContent';
14
15
 
15
16
  export type { ContentType } from './SearchTypeResult';
16
17
 
17
- export { SearchTypeResult, SearchHeader, SearchFieldHeader, SearchNotionsResult, SearchSubjectResult };
18
+ export {
19
+ SearchTypeResult,
20
+ SearchHeader,
21
+ SearchFieldHeader,
22
+ SearchNotionsResult,
23
+ SearchSubjectResult,
24
+ SearchFilterContent,
25
+ };
package/src/index.ts CHANGED
@@ -134,6 +134,7 @@ export {
134
134
  SearchFieldHeader,
135
135
  SearchNotionsResult,
136
136
  SearchSubjectResult,
137
+ SearchFilterContent,
137
138
  } from './SearchTypeResult';
138
139
 
139
140
  export { default as constants } from './model';
@@ -214,3 +215,5 @@ export {
214
215
  export { default as ContentCard } from './ContentCard';
215
216
 
216
217
  export { default as CopyParagraphButton } from './CopyParagraphButton';
218
+
219
+ export { Notion, ConceptNotion } from './Notion';
@@ -116,6 +116,7 @@ const messages = {
116
116
  useFilter: 'Use filter',
117
117
  closeFilter: 'Close filter',
118
118
  removeFilter: 'Remove filter {{filterName}}',
119
+ additionalSubjectFilters: '+ {{count}} subjects',
119
120
  coreRelevance: 'Core content',
120
121
  supplementaryRelevance: 'Supplementary content',
121
122
  resourceTypeFilter: {
@@ -124,20 +125,25 @@ const messages = {
124
125
  },
125
126
  },
126
127
  resultType: {
127
- showing: 'Showing {{fromCount}} to {{toCount}} of {{totalCount}}',
128
+ showing: 'Showing {{count}} of {{totalCount}} {{contentType}}',
129
+ showingAll: 'Showing all',
128
130
  showMore: 'Show more',
129
131
  showAll: 'Show all',
132
+ toTopOfPage: 'To top of page',
130
133
  toSubjectPageLabel: 'Go to subject page',
131
134
  all: 'All',
135
+ allContentTypes: 'All content-types',
132
136
  hits: '{{count}} hits',
133
- showingSearchPhrase: 'Showing results for:',
137
+ showingSearchPhrase: 'Showing hits for',
138
+ searchPhraseSuggestion: 'Search instead for',
134
139
  showingCompetenceGoalSearchPhrase: 'Showing results for competence goals {text}',
135
- searchPhraseSuggestion: 'Search instead for:',
136
140
  notionLabels: 'Used in',
137
141
  notionsHeading: 'Explanations',
138
142
  notionsRemove: 'Remove',
139
143
  showVideo: 'Watch video',
140
144
  showNotion: 'Show notion',
145
+ gridView: 'Grid-view',
146
+ listView: 'List-view',
141
147
  },
142
148
  contextModal: {
143
149
  button: '+ {{count}} more contexts',
@@ -548,6 +554,7 @@ const messages = {
548
554
  'source-material': 'Source material',
549
555
  'assessment-resources': 'Assessment resource',
550
556
  topic: 'Topic',
557
+ 'multidisciplinary-topic': 'Multidisciplinary case',
551
558
  },
552
559
  modal: {
553
560
  closeModal: 'Close',
@@ -834,6 +841,9 @@ const messages = {
834
841
  },
835
842
  readMoreDescriptionLabel: 'show more',
836
843
  },
844
+ h5p: {
845
+ reuse: 'Use H5P',
846
+ },
837
847
  video: {
838
848
  download: 'Download video',
839
849
  reuse: 'Use video',
@@ -845,6 +855,7 @@ const messages = {
845
855
  },
846
856
  concept: {
847
857
  showDescription: 'Show concept description',
858
+ reuse: 'Use concept',
848
859
  error: {
849
860
  title: 'An error occurred',
850
861
  content: 'Could not load the description of the concept.',
@@ -895,6 +906,10 @@ const messages = {
895
906
  open: 'Open menu',
896
907
  close: 'Close menu',
897
908
  },
909
+ factbox: {
910
+ open: 'Open fact box',
911
+ close: 'Close fact box',
912
+ },
898
913
  };
899
914
 
900
915
  export default messages;
@@ -116,6 +116,7 @@ const messages = {
116
116
  useFilter: 'Bruk filter',
117
117
  closeFilter: 'Lukk filter',
118
118
  removeFilter: 'Fjern filter {{filterName}}',
119
+ additionalSubjectFilters: '+ {{count}} fag',
119
120
  coreRelevance: 'Kjernestoff',
120
121
  supplementaryRelevance: 'Tilleggsstoff',
121
122
  resourceTypeFilter: {
@@ -124,20 +125,25 @@ const messages = {
124
125
  },
125
126
  },
126
127
  resultType: {
127
- showing: 'Viser {{fromCount}} til {{toCount}} av {{totalCount}}',
128
+ showing: 'Viser {{count}} av {{totalCount}} {{contentType}}',
129
+ showingAll: 'Viser alle',
128
130
  showMore: 'Vis mer',
129
131
  showAll: 'Vis alle',
132
+ toTopOfPage: 'Til toppen',
130
133
  toSubjectPageLabel: 'Gå til fagsiden',
131
134
  all: 'Alle',
132
- hits: '{{count}} Treff',
133
- showingSearchPhrase: 'Viser resultater for',
135
+ allContentTypes: 'Alle innholdstyper',
136
+ hits: '{{count}} treff',
137
+ showingSearchPhrase: 'Viser treff for',
134
138
  showingCompetenceGoalSearchPhrase: 'Viser resultater for kompetansemål {text}',
135
- searchPhraseSuggestion: 'Søk i stedet for',
139
+ searchPhraseSuggestion: 'Søk heller',
136
140
  notionLabels: 'Brukes i',
137
141
  notionsHeading: 'Begrepsforklaring',
138
142
  notionsRemove: 'Fjern',
139
143
  showVideo: 'Se video',
140
144
  showNotion: 'Se forklaring',
145
+ gridView: 'Gallerivisning',
146
+ listView: 'Listevisning',
141
147
  },
142
148
  contextModal: {
143
149
  button: '+ {{count}} flere steder',
@@ -546,6 +552,7 @@ const messages = {
546
552
  'source-material': 'Kildemateriale',
547
553
  'assessment-resources': 'Vurderingsressurs',
548
554
  topic: 'Emne',
555
+ 'multidisciplinary-topic': 'Tverrfaglig case',
549
556
  },
550
557
  modal: {
551
558
  closeModal: 'Lukk',
@@ -832,6 +839,9 @@ const messages = {
832
839
  },
833
840
  readMoreDescriptionLabel: 'vis mer',
834
841
  },
842
+ h5p: {
843
+ reuse: 'Bruk H5P',
844
+ },
835
845
  video: {
836
846
  download: 'Last ned video',
837
847
  reuse: 'Bruk video',
@@ -843,6 +853,7 @@ const messages = {
843
853
  },
844
854
  concept: {
845
855
  showDescription: 'Vis beskrivelsen av forklaringen.',
856
+ reuse: 'Bruk forklaring',
846
857
  error: {
847
858
  title: 'En feil oppstod',
848
859
  content: 'Kunne ikke laste beskrivelsen av forklaringen.',
@@ -893,6 +904,10 @@ const messages = {
893
904
  open: 'Åpne meny',
894
905
  close: 'Lukk meny',
895
906
  },
907
+ factbox: {
908
+ open: 'Åpne faktaboks',
909
+ close: 'Lukk faktaboks',
910
+ },
896
911
  };
897
912
 
898
913
  export default messages;
@@ -116,6 +116,7 @@ const messages = {
116
116
  useFilter: 'Bruk filter',
117
117
  removeFilter: 'Fjern filter {{filterName}}',
118
118
  closeFilter: 'Lukk filter',
119
+ additionalSubjectFilters: '+ {{count}} fag',
119
120
  coreRelevance: 'Kjernestoff',
120
121
  supplementaryRelevance: 'Tilleggsstoff',
121
122
  resourceTypeFilter: {
@@ -124,20 +125,25 @@ const messages = {
124
125
  },
125
126
  },
126
127
  resultType: {
127
- showing: 'Viser {{fromCount}} til {{toCount}} av {{totalCount}}',
128
+ showing: 'Viser {{count}} av {{totalCount}} {{contentType}}',
129
+ showingAll: 'Viser alle',
128
130
  showMore: 'Vis meir',
129
131
  showAll: 'Vis alle',
132
+ toTopOfPage: 'Til toppen',
130
133
  toSubjectPageLabel: 'Gå til fagsida',
131
134
  all: 'Alle',
132
- hits: '{{count}} Treff',
133
- showingSearchPhrase: 'Viser resultat for',
135
+ allContentTypes: 'Alle innhaldstyper',
136
+ hits: '{{count}} treff',
137
+ showingSearchPhrase: 'Viser treff for',
138
+ searchPhraseSuggestion: 'Søk heller',
134
139
  showingCompetenceGoalSearchPhrase: 'Viser resultat for kompetansemål {text}',
135
- searchPhraseSuggestion: 'Søk i staden for',
136
140
  notionLabels: 'Brukes i',
137
141
  notionsHeading: 'Begrepsforklaring',
138
142
  notionsRemove: 'Fjern',
139
143
  showVideo: 'Sjå video',
140
144
  showNotion: 'Sjå forklaring',
145
+ gridView: 'Gallerivisning',
146
+ listView: 'Listevisning',
141
147
  },
142
148
  contextModal: {
143
149
  button: '+ {{count}} fleire stader',
@@ -547,6 +553,7 @@ const messages = {
547
553
  'source-material': 'Kjeldemateriale',
548
554
  'assessment-resources': 'Vurderingsressurs',
549
555
  topic: 'Emne',
556
+ 'multidisciplinary-topic': 'Tverrfagleg case',
550
557
  },
551
558
  modal: {
552
559
  closeModal: 'Lukk',
@@ -833,6 +840,9 @@ const messages = {
833
840
  },
834
841
  readMoreDescriptionLabel: 'vis meir',
835
842
  },
843
+ h5p: {
844
+ reuse: 'Bruk H5P',
845
+ },
836
846
  video: {
837
847
  download: 'Last ned video',
838
848
  reuse: 'Bruk video',
@@ -844,6 +854,7 @@ const messages = {
844
854
  },
845
855
  concept: {
846
856
  showDescription: 'Vis skildring av forklaringa',
857
+ reuse: 'Bruk forklaring',
847
858
  error: {
848
859
  title: 'Ein feil oppstod',
849
860
  content: 'Kunne ikkje laste skildringa av forklaringa.',
@@ -894,6 +905,10 @@ const messages = {
894
905
  open: 'Åpne meny',
895
906
  close: 'Lukk meny',
896
907
  },
908
+ factbox: {
909
+ open: 'Åpne faktaboks',
910
+ close: 'Lukk faktaboks',
911
+ },
897
912
  };
898
913
 
899
914
  export default messages;
@@ -14,3 +14,4 @@ export const EXTERNAL_LEARNING_RESOURCES = 'external-learning-resources';
14
14
  export const SOURCE_MATERIAL = 'source-material';
15
15
  export const LEARNING_PATH = 'learning-path';
16
16
  export const TOPIC = 'topic';
17
+ export const MULTIDISCIPLINARY_TOPIC = 'multidisciplinary-topic';
package/src/shapes.js CHANGED
@@ -78,6 +78,7 @@ export const ContentTypeShape = PropTypes.oneOf([
78
78
  contentTypes.SOURCE_MATERIAL,
79
79
  contentTypes.LEARNING_PATH,
80
80
  contentTypes.TOPIC,
81
+ contentTypes.MULTIDISCIPLINARY_TOPIC,
81
82
  'beta',
82
83
  'ndla-film',
83
84
  'ndla-film has-image',
package/src/types.ts CHANGED
@@ -52,6 +52,7 @@ export interface Copyright {
52
52
  creators: Array<Contributor>;
53
53
  rightsholders: Array<Contributor>;
54
54
  processors: Array<Contributor>;
55
+ origin?: string;
55
56
  }
56
57
 
57
58
  export interface FootNote {