@ndla/ui 3.3.9 → 3.3.11

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 (70) hide show
  1. package/es/Article/Article.js +23 -1
  2. package/es/Article/ArticleNotions.js +80 -32
  3. package/es/Breadcrumblist/Breadcrumblist.js +14 -10
  4. package/es/CloseButton/CloseButton.js +62 -0
  5. package/es/CloseButton/index.js +9 -0
  6. package/es/Frontpage/FrontpageProgramMenu.js +10 -10
  7. package/es/MediaList/MediaList.js +22 -73
  8. package/es/MessageBox/MessageBox.js +146 -78
  9. package/es/MessageBox/MessageBoxTag.js +37 -0
  10. package/es/MessageBox/index.js +3 -1
  11. package/es/NDLAFilm/FilmSlideshow.js +2 -1
  12. package/es/Programme/Programme.js +15 -8
  13. package/es/SearchTypeResult/SearchNotionItem.js +12 -12
  14. package/es/SearchTypeResult/SearchNotionsResult.js +9 -14
  15. package/es/index.js +2 -1
  16. package/es/locale/messages-en.js +10 -0
  17. package/es/locale/messages-nb.js +10 -0
  18. package/es/locale/messages-nn.js +10 -0
  19. package/lib/Article/Article.d.ts +3 -1
  20. package/lib/Article/Article.js +25 -3
  21. package/lib/Article/ArticleNotions.js +79 -30
  22. package/lib/Breadcrumblist/Breadcrumblist.d.ts +2 -1
  23. package/lib/Breadcrumblist/Breadcrumblist.js +15 -10
  24. package/lib/CloseButton/CloseButton.d.ts +6 -0
  25. package/lib/CloseButton/CloseButton.js +69 -0
  26. package/lib/CloseButton/index.d.ts +9 -0
  27. package/lib/CloseButton/index.js +15 -0
  28. package/lib/Frontpage/FrontpageProgramMenu.js +10 -10
  29. package/lib/MediaList/MediaList.d.ts +48 -0
  30. package/lib/MediaList/MediaList.js +24 -78
  31. package/lib/MediaList/index.d.ts +8 -0
  32. package/lib/MessageBox/MessageBox.d.ts +22 -6
  33. package/lib/MessageBox/MessageBox.js +146 -77
  34. package/lib/MessageBox/MessageBoxTag.d.ts +12 -0
  35. package/lib/MessageBox/MessageBoxTag.js +44 -0
  36. package/lib/MessageBox/index.d.ts +3 -1
  37. package/lib/MessageBox/index.js +22 -2
  38. package/lib/Programme/Programme.d.ts +2 -1
  39. package/lib/Programme/Programme.js +18 -9
  40. package/lib/SearchTypeResult/SearchNotionItem.js +12 -12
  41. package/lib/SearchTypeResult/SearchNotionsResult.js +8 -13
  42. package/lib/index.d.ts +2 -1
  43. package/lib/index.js +23 -0
  44. package/lib/locale/messages-en.d.ts +10 -0
  45. package/lib/locale/messages-en.js +10 -0
  46. package/lib/locale/messages-nb.d.ts +10 -0
  47. package/lib/locale/messages-nb.js +10 -0
  48. package/lib/locale/messages-nn.d.ts +10 -0
  49. package/lib/locale/messages-nn.js +10 -0
  50. package/package.json +9 -9
  51. package/src/Article/Article.tsx +17 -0
  52. package/src/Article/ArticleNotions.tsx +10 -7
  53. package/src/Breadcrumblist/Breadcrumblist.tsx +5 -3
  54. package/src/CloseButton/CloseButton.tsx +40 -0
  55. package/src/CloseButton/index.ts +11 -0
  56. package/src/Frontpage/FrontpageProgramMenu.tsx +1 -0
  57. package/src/MediaList/MediaList.tsx +158 -0
  58. package/src/MediaList/{index.js → index.ts} +0 -0
  59. package/src/MessageBox/MessageBox.tsx +117 -96
  60. package/src/MessageBox/MessageBoxTag.tsx +35 -0
  61. package/src/MessageBox/index.ts +3 -1
  62. package/src/NDLAFilm/FilmSlideshow.tsx +1 -0
  63. package/src/Programme/Programme.tsx +7 -3
  64. package/src/SearchTypeResult/SearchNotionItem.tsx +0 -1
  65. package/src/SearchTypeResult/SearchNotionsResult.tsx +3 -8
  66. package/src/index.ts +2 -1
  67. package/src/locale/messages-en.ts +14 -0
  68. package/src/locale/messages-nb.ts +14 -0
  69. package/src/locale/messages-nn.ts +14 -0
  70. package/src/MediaList/MediaList.jsx +0 -182
@@ -0,0 +1,158 @@
1
+ /*
2
+ * Copyright (c) 2016-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 {
11
+ LicenseDescription,
12
+ getLicenseByAbbreviation,
13
+ getResourceTypeNamespace,
14
+ isCreativeCommonsLicense,
15
+ metaTypes,
16
+ } from '@ndla/licenses';
17
+ import BEMHelper from 'react-bem-helper';
18
+ import { uuid } from '@ndla/util';
19
+
20
+ const oClasses = new BEMHelper({
21
+ name: 'media',
22
+ prefix: 'o-',
23
+ });
24
+
25
+ const cClasses = new BEMHelper({
26
+ name: 'medialist',
27
+ prefix: 'c-',
28
+ });
29
+
30
+ interface MediaListProps {
31
+ children: ReactNode;
32
+ }
33
+
34
+ export const MediaList = ({ children }: MediaListProps) => <ul {...cClasses()}>{children}</ul>;
35
+
36
+ interface MediaListItemProps {
37
+ children: ReactNode;
38
+ }
39
+ export const MediaListItem = ({ children }: MediaListItemProps) => (
40
+ <li {...oClasses(undefined, undefined, cClasses('item').className)}>{children}</li>
41
+ );
42
+
43
+ interface MediaListItemImageProps {
44
+ children: ReactNode;
45
+ }
46
+ export const MediaListItemImage = ({ children }: MediaListItemImageProps) => (
47
+ <div {...oClasses('img', undefined, cClasses('img').className)}>
48
+ <div>{children}</div>
49
+ </div>
50
+ );
51
+
52
+ interface MediaListCCLinkProps {
53
+ children: ReactNode;
54
+ url: string;
55
+ }
56
+ export const MediaListCCLink = ({ children, url }: MediaListCCLinkProps) => (
57
+ <a className="c-figure-license__link" target="_blank" rel="noopener noreferrer license" href={url}>
58
+ {children}
59
+ </a>
60
+ );
61
+
62
+ interface MediaListItemBodyProps {
63
+ children: ReactNode;
64
+ license: string;
65
+ locale: string;
66
+ resourceUrl?: string;
67
+ resourceType?: 'video' | 'image' | 'audio' | 'text' | 'h5p';
68
+ messages?: {
69
+ modelPremission?: string;
70
+ };
71
+ title?: string;
72
+ }
73
+
74
+ export const MediaListItemBody = ({
75
+ children,
76
+ license: licenseAbbreviation,
77
+ messages,
78
+ title,
79
+ locale,
80
+ resourceUrl = '', // defaults to current page
81
+ resourceType,
82
+ }: MediaListItemBodyProps) => {
83
+ const license = getLicenseByAbbreviation(licenseAbbreviation, locale);
84
+ const containerProps = isCreativeCommonsLicense(license.rights)
85
+ ? {
86
+ ...oClasses('body', undefined, cClasses('body').className),
87
+ 'xmlns:cc': 'https://creativecommons.org/ns#',
88
+ 'xmlns:dct': 'http://purl.org/dc/terms/',
89
+ about: resourceUrl,
90
+ }
91
+ : {
92
+ ...oClasses('body', undefined, cClasses('body').className),
93
+ };
94
+
95
+ const metaResourceType = getResourceTypeNamespace(resourceType);
96
+
97
+ return (
98
+ <div {...containerProps}>
99
+ {/* @ts-ignore */}
100
+ {metaResourceType && <span rel="dct:type" href={metaResourceType} style={{ display: 'none' }} />}
101
+ {title ? <h3 className="c-medialist__title">{title} </h3> : null}
102
+ <LicenseDescription locale={locale} messages={messages} licenseRights={license.rights} highlightCC />
103
+ <MediaListCCLink url={license.url}>{license.linkText}</MediaListCCLink>
104
+ {children}
105
+ </div>
106
+ );
107
+ };
108
+
109
+ interface MediaListItemActionsProps {
110
+ children: ReactNode;
111
+ }
112
+ export const MediaListItemActions = ({ children }: MediaListItemActionsProps) => (
113
+ <div {...cClasses('actions')}>{children}</div>
114
+ );
115
+
116
+ const isLink = (text: string) => text.startsWith('http') || text.startsWith('https');
117
+
118
+ interface HandleLinkProps {
119
+ text: string;
120
+ children: ReactNode;
121
+ }
122
+
123
+ export const HandleLink = ({ text, children }: HandleLinkProps) => {
124
+ if (isLink(text)) {
125
+ return (
126
+ <a href={text} target="_blank" rel="noopener noreferrer">
127
+ {children}
128
+ </a>
129
+ );
130
+ }
131
+ return <span>{children}</span>;
132
+ };
133
+
134
+ const attributionTypes = [metaTypes.author, metaTypes.copyrightHolder, metaTypes.contributor];
135
+
136
+ interface MediaListItemMetaProps {
137
+ items?: {
138
+ label: string;
139
+ description: string;
140
+ metaType: string;
141
+ }[];
142
+ }
143
+
144
+ export const MediaListItemMeta = ({ items = [] }: MediaListItemMetaProps) => {
145
+ const attributionItems = items.filter((item) => attributionTypes.some((type) => type === item.metaType));
146
+ const attributionMeta = attributionItems.map((item) => `${item.label}: ${item.description}`).join(', ');
147
+
148
+ return (
149
+ //@ts-ignore
150
+ <ul {...cClasses('actions')} property="cc:attributionName" content={attributionMeta}>
151
+ {items.map((item) => (
152
+ <li key={uuid()} className="c-medialist__meta-item">
153
+ {item.label}: <HandleLink text={item.description}>{item.description}</HandleLink>
154
+ </li>
155
+ ))}
156
+ </ul>
157
+ );
158
+ };
File without changes
@@ -1,63 +1,92 @@
1
- import React from 'react';
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, { useState } from 'react';
2
10
  import styled from '@emotion/styled';
3
11
  import Sticky from 'react-sticky-el';
4
12
  import { breakpoints, fonts, mq, spacing } from '@ndla/core';
5
- // @ts-ignore
6
- import Button from '@ndla/button';
7
- import { Cross } from '@ndla/icons/action';
8
- import { InformationOutline } from '@ndla/icons/common';
13
+ import { InformationOutline, HumanMaleBoard } from '@ndla/icons/common';
9
14
  import { WithTranslation, withTranslation } from 'react-i18next';
15
+ import { CloseButton } from '../CloseButton';
10
16
 
17
+ export enum MessageBoxType {
18
+ ghost = 'ghost',
19
+ fullpage = 'fullpage',
20
+ medium = 'medium',
21
+ }
11
22
  type WrapperProps = {
12
- boxType?: 'info';
23
+ boxType?: MessageBoxType;
13
24
  };
14
25
 
15
- const colorsByType = (type: WrapperProps['boxType']) => {
16
- const colors = {
17
- color: '#551700',
18
- backgroundColor: '#FEEFB3',
19
- };
26
+ const StyleByType = (type: WrapperProps['boxType']) => {
27
+ const styles = {
28
+ margin: '1px',
29
+ color: '#444444',
30
+ backgroundColor: '#f9f4c8',
31
+ border: 'none',
32
+ display: 'flex',
33
+ width: 'auto',
34
+ position: 'relative',
35
+ transform: 'auto',
36
+ left: 'auto',
37
+ }; //Different CSS properties for different types of message-boxes
20
38
  switch (type) {
21
- case 'info':
22
- default:
39
+ case 'fullpage':
40
+ styles.margin = '0 auto';
41
+ styles.display = 'none';
42
+ styles.width = '100vw';
43
+ styles.position = 'relative';
44
+ styles.left = '50%';
45
+ styles.transform = 'translateX(-50%)';
46
+ break;
47
+ case 'medium':
48
+ styles.margin = '0px';
49
+ break;
50
+ case 'ghost':
51
+ styles.backgroundColor = 'transparent';
52
+ styles.border = '1px solid #D1D6DB';
53
+ styles.color = '#444444';
54
+
23
55
  break;
24
56
  }
25
- return colors;
57
+ return styles;
26
58
  };
27
59
 
28
60
  const Wrapper = styled.div<WrapperProps>`
29
- background: ${(props) => colorsByType(props.boxType).backgroundColor};
30
- color: ${(props) => colorsByType(props.boxType).color};
61
+ background: ${(props) => StyleByType(props.boxType).backgroundColor};
62
+ color: ${(props) => StyleByType(props.boxType).color};
31
63
  font-size: 18px;
32
64
  line-height: 32px;
33
- box-shadow: 0 4px 4px rgba(0, 0, 0, 0.12);
65
+ font-family: ${fonts.sans};
34
66
  display: flex;
35
67
  padding: ${spacing.small};
36
- position: relative;
68
+ position: ${(props) => StyleByType(props.boxType).position};
69
+ border: ${(props) => StyleByType(props.boxType).border};
70
+ border-radius: 5px;
71
+ transform: ${(props) => StyleByType(props.boxType).transform};
72
+ left: ${(props) => StyleByType(props.boxType).left};
73
+ z-index: 10;
74
+ width: ${(props) => StyleByType(props.boxType).width};
37
75
  `;
38
76
 
39
- const Label = styled.label`
40
- font-weight: ${fonts.weight.bold};
41
- display: inline-block;
42
- margin-right: ${spacing.small};
43
- ${mq.range({ until: breakpoints.tabletWide })} {
44
- font-size: 18px;
45
- font-weight: ${fonts.weight.semibold};
46
- }
47
- `;
48
-
49
- const InfoWrapper = styled.div`
50
- margin: 0 auto;
51
- padding: 0 100px;
77
+ const InfoWrapper = styled.div<WrapperProps>`
78
+ margin: ${(props) => StyleByType(props.boxType).margin};
79
+ padding: 10px;
52
80
  display: flex;
53
81
  ${mq.range({ until: breakpoints.tabletWide })} {
54
82
  padding: 0 90px 0 0;
55
83
  }
56
84
  ${mq.range({ until: breakpoints.mobileWide })} {
57
- padding: 0 50px 0 0;
85
+ padding: 0 5px 0 0;
86
+ font-size: 16px;
58
87
  }
59
88
  `;
60
- const TextWrapper = styled.div`
89
+ const TextWrapper = styled.div<WrapperProps>`
61
90
  display: flex;
62
91
  align-items: center;
63
92
  flex-wrap: wrap;
@@ -67,88 +96,80 @@ const TextWrapper = styled.div`
67
96
  }
68
97
  `;
69
98
 
70
- const IconWrapper = styled.div`
99
+ const IconWrapper = styled.div<WrapperProps>`
71
100
  padding-right: ${spacing.small};
72
- display: flex;
101
+ display: ${(props) => StyleByType(props.boxType).display};
73
102
  align-items: flex-start;
74
103
  ${mq.range({ from: breakpoints.tabletWide })} {
75
104
  padding-top: 4px;
76
105
  }
77
106
  `;
78
107
 
79
- const CloseButtonWrapper = styled.div`
80
- position: absolute;
81
- top: 13px;
82
- right: ${spacing.small};
83
- display: flex;
84
- justify-content: flex-end;
85
- ${mq.range({ from: breakpoints.tabletWide })} {
86
- top: 16px;
87
- }
88
- `;
89
-
90
- const CloseButton = styled(Button)`
91
- display: flex;
92
- justify-content: center;
93
- align-items: center;
94
- font-weight: ${fonts.weight.semibold};
95
- font-size: 16px;
96
- color: ${(props) => colorsByType(props.boxType).color};
97
- &:hover {
98
- color: ${(props) => colorsByType(props.boxType).color};
99
- }
108
+ const LinkWrapper = styled.div`
109
+ display: block;
110
+ width: 100%;
111
+ background-color: #f9f4c8;
112
+ padding-bottom: 20px;
113
+ margin-top: -2px;
114
+ padding-left: 58px;
115
+ border-radius: 0px 0px 5px 5px;
100
116
  ${mq.range({ until: breakpoints.mobileWide })} {
101
- flex-direction: column-reverse;
117
+ padding-left: 45px;
102
118
  }
103
119
  `;
104
-
105
- const CloseButtonText = styled.span`
106
- margin-right: ${spacing.small};
107
- line-height: 1;
120
+ const Link = styled.a`
121
+ color: #20588f;
122
+ font-size: 16px;
123
+ padding-bottom: 1px;
124
+ margin: 0px 40px 1px 2px;
125
+ font-family: ${fonts.sans};
108
126
  ${mq.range({ until: breakpoints.mobileWide })} {
109
- margin-right: 0;
110
- ${fonts.sizes('14px', '18px')};
111
- font-weight: ${fonts.weight.normal};
127
+ margin: 0px 15px 1px 5px;
128
+ box-shadow: none;
112
129
  }
113
130
  `;
114
131
 
132
+ type LinkProps = {
133
+ href?: string;
134
+ text?: string;
135
+ };
115
136
  type Props = {
116
137
  type?: WrapperProps['boxType'];
117
- heading?: string;
118
138
  sticky?: boolean;
119
- onClose?: () => void;
120
- children: React.ReactNode;
139
+ onClose?: boolean;
140
+ children?: string;
141
+ links?: LinkProps[];
121
142
  };
122
143
 
123
- export const MessageBox = ({
124
- heading,
125
- type = 'info',
126
- sticky = true,
127
- onClose,
128
- children,
129
- t,
130
- }: Props & WithTranslation) => (
131
- <Sticky disabled={!sticky} stickyStyle={{ zIndex: 9999 }}>
132
- <Wrapper boxType={type}>
133
- <InfoWrapper>
134
- <IconWrapper>
135
- <InformationOutline style={{ width: '24px', height: '24px' }} />
136
- </IconWrapper>
137
- <TextWrapper>
138
- {heading && <Label>{heading}</Label>}
139
- {children}
140
- </TextWrapper>
141
- </InfoWrapper>
142
- {onClose && (
143
- <CloseButtonWrapper>
144
- <CloseButton link onClick={onClose}>
145
- <CloseButtonText>{t('close')}</CloseButtonText>
146
- <Cross style={{ width: '24px', height: '24px' }} />
147
- </CloseButton>
148
- </CloseButtonWrapper>
144
+ export const MessageBox = ({ type, sticky = false, onClose, children, links, t }: Props & WithTranslation) => {
145
+ const [hideMessageBox, setHideMessageBox] = useState(false);
146
+ const onCloseMessageBox = () => {
147
+ setHideMessageBox(true);
148
+ };
149
+ const Icon = type === 'ghost' ? HumanMaleBoard : InformationOutline;
150
+ return (
151
+ //StickyStyle top:84 makes sure that the messagebox sits beneath the masthead (header ) and the topOffsett sets it so that it applies when reaching the top of the messagebox
152
+ <Sticky disabled={!sticky} stickyStyle={{ zIndex: 9998, top: 84 }} topOffset={-84}>
153
+ <Wrapper boxType={type} style={{ display: hideMessageBox ? 'none' : 'flex' }}>
154
+ <InfoWrapper boxType={type}>
155
+ <IconWrapper boxType={type}>
156
+ <Icon style={{ width: '24px', height: '24px' }} />
157
+ </IconWrapper>
158
+ <TextWrapper>{children}</TextWrapper>
159
+ </InfoWrapper>
160
+ {onClose && <CloseButton onClick={onCloseMessageBox} color="#444444" />}
161
+ </Wrapper>
162
+
163
+ {links && (
164
+ //loops through the links passed in as properties if there are any and creates a working link for each of them
165
+ <LinkWrapper style={{ display: hideMessageBox ? 'none' : 'flex' }}>
166
+ {links.map((x) => (
167
+ <Link href={x.href}>{x.text}</Link>
168
+ ))}
169
+ </LinkWrapper>
149
170
  )}
150
- </Wrapper>
151
- </Sticky>
152
- );
171
+ </Sticky>
172
+ );
173
+ };
153
174
 
154
175
  export default withTranslation()(MessageBox);
@@ -0,0 +1,35 @@
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 { useTranslation } from 'react-i18next';
11
+
12
+ import styled from '@emotion/styled';
13
+
14
+ const MiniMesssage = styled.div`
15
+ background-color: #f9f4c8;
16
+ text-align: center;
17
+ display: inline-block;
18
+ padding: 5px;
19
+ text-transform: uppercase;
20
+ font-weight: 600;
21
+ font-size: 14px;
22
+ margin-left: 10px;
23
+ margin-bottom: 10px;
24
+ border-radius: 5px;
25
+ `;
26
+
27
+ type Props = {
28
+ tagMessage: string;
29
+ };
30
+ export const MessageBoxTag = ({ tagMessage }: Props) => {
31
+ const { t } = useTranslation();
32
+ return <MiniMesssage>{t(tagMessage)}</MiniMesssage>;
33
+ };
34
+
35
+ export default MessageBoxTag;
@@ -7,5 +7,7 @@
7
7
  */
8
8
 
9
9
  import MessageBox from './MessageBox';
10
+ import MessageBoxTag from './MessageBoxTag';
11
+ import { MessageBoxType } from './MessageBox';
10
12
 
11
- export { MessageBox };
13
+ export { MessageBox, MessageBoxTag, MessageBoxType };
@@ -7,6 +7,7 @@
7
7
  */
8
8
 
9
9
  import React, { useCallback, useEffect, useRef, useState } from 'react';
10
+ // @ts-ignore
10
11
  import { SwipeEventData, useSwipeable } from 'react-swipeable';
11
12
  import BEMHelper from 'react-bem-helper';
12
13
  import SafeLink from '@ndla/safelink';
@@ -1,11 +1,12 @@
1
1
  import React from 'react';
2
2
  import styled from '@emotion/styled';
3
3
  import { breakpoints, mq, spacing } from '@ndla/core';
4
+ import { useTranslation } from 'react-i18next';
4
5
  import LayoutItem, { OneColumn } from '../Layout';
5
- import { NavigationHeading } from '../Navigation';
6
6
  import ProgrammeSubjects from './ProgrammeSubjects';
7
7
  import { GradesProps } from './ProgrammeSubjects';
8
-
8
+ import MessageBox from '../MessageBox/MessageBox';
9
+ import { NavigationHeading } from '..';
9
10
  const StyledWrapper = styled.div`
10
11
  display: flex;
11
12
  flex-direction: column;
@@ -63,9 +64,11 @@ const SubjectsWrapper = styled.div`
63
64
  type Props = GradesProps & {
64
65
  heading?: string;
65
66
  image?: string;
67
+ messageBoxText?: string;
66
68
  };
67
69
 
68
- export const Programme = ({ heading, image, grades, selectedGrade, onChangeGrade }: Props) => {
70
+ export const Programme = ({ heading, image, grades, selectedGrade, onChangeGrade, messageBoxText }: Props) => {
71
+ const { t } = useTranslation();
69
72
  return (
70
73
  <StyledWrapper>
71
74
  <StyledBackground image={image} />
@@ -74,6 +77,7 @@ export const Programme = ({ heading, image, grades, selectedGrade, onChangeGrade
74
77
  <LayoutItem layout="extend">
75
78
  <StyledContentWrapper>
76
79
  <NavigationHeading>{heading}</NavigationHeading>
80
+ {messageBoxText && <MessageBox>{t(messageBoxText)}</MessageBox>}
77
81
  <SubjectsWrapper>
78
82
  <ProgrammeSubjects grades={grades} selectedGrade={selectedGrade} onChangeGrade={onChangeGrade} />
79
83
  </SubjectsWrapper>
@@ -48,7 +48,6 @@ const ItemWrapper = styled.div<ItemWrapperProps>`
48
48
  const TextWrapper = styled.div``;
49
49
  const DescriptionWrapper = styled.div`
50
50
  ${fonts.sizes('18px', '26px')};
51
- font-family: ${fonts.serif};
52
51
  `;
53
52
 
54
53
  const MediaWrapper = styled.div`
@@ -10,7 +10,8 @@ import React from 'react';
10
10
  import styled from '@emotion/styled';
11
11
  import { fonts, mq, breakpoints, spacing } from '@ndla/core';
12
12
  // @ts-ignore
13
- import Button from '@ndla/button';
13
+ import { ModalCloseButton } from '@ndla/modal';
14
+ // @ts-ignore
14
15
  import { withTranslation, WithTranslation } from 'react-i18next';
15
16
  import SearchNotionItem, { SearchNotionItemProps } from './SearchNotionItem';
16
17
 
@@ -47,10 +48,6 @@ const HeadingCount = styled.span`
47
48
  text-transform: lowercase;
48
49
  `;
49
50
 
50
- const ButtonRemoveText = styled.span`
51
- ${fonts.sizes('18px', '22px')};
52
- `;
53
-
54
51
  type Props = {
55
52
  items: SearchNotionItemProps[];
56
53
  totalCount: number;
@@ -65,9 +62,7 @@ const SearchNotionsResult = ({ items, totalCount, onRemove, renderMarkdown, t }:
65
62
  {t(`searchPage.resultType.notionsHeading`)}
66
63
  <HeadingCount>{t(`searchPage.resultType.hits`, { count: totalCount })}</HeadingCount>
67
64
  </Heading>
68
- <Button onClick={onRemove} link>
69
- <ButtonRemoveText>{t(`searchPage.resultType.notionsRemove`)}</ButtonRemoveText>
70
- </Button>
65
+ <ModalCloseButton onClick={onRemove} />
71
66
  </HeadingWrapper>
72
67
  {items.map((item) => (
73
68
  <SearchNotionItem key={item.id} {...item} renderMarkdown={renderMarkdown} />
package/src/index.ts CHANGED
@@ -115,8 +115,9 @@ export { default as CreatedBy } from './CreatedBy';
115
115
 
116
116
  export { default as Breadcrumblist } from './Breadcrumblist';
117
117
 
118
- export { MessageBox } from './MessageBox';
118
+ export { MessageBox, MessageBoxTag, MessageBoxType } from './MessageBox';
119
119
 
120
+ export { CloseButton } from './CloseButton';
120
121
  export { default as AudioPlayer, initAudioPlayers } from './AudioPlayer';
121
122
 
122
123
  export { NavigationHeading, NavigationBox, NavigationTopicAbout } from './Navigation';
@@ -313,6 +313,20 @@ const messages = {
313
313
  h5p: 'Interactive',
314
314
  },
315
315
  },
316
+ messageBoxInfo: {
317
+ outdatedCoursePlan:
318
+ 'This course is not updated to the current curriculum. Follow this link to find the updated version of the course: ',
319
+ updateBrowser:
320
+ 'Your browser is outdated. Update it, or find a safe and updated browser on https://browsehappy.com.',
321
+ noContent: 'We are sorry, but we do not yet offer any program courses.',
322
+ feide: 'This resource is accessible only to teachers who are logged in with Feide.',
323
+ resources:
324
+ 'This is not a complete course produced by NDLA, but a collection of resources we hope you will find useful.',
325
+ beta: 'This course is in beta.',
326
+ outdatedSubject: 'This topic is part of a course that is not updated to the current curriculum.',
327
+ newVersion:
328
+ 'This learning resource is not updated to the current curriculum. You can find an updated version here: ',
329
+ },
316
330
  article: {
317
331
  edition: 'Edition',
318
332
  publisher: 'Publisher',
@@ -312,6 +312,20 @@ const messages = {
312
312
  h5p: 'Interaktiv',
313
313
  },
314
314
  },
315
+ messageBoxInfo: {
316
+ outdatedCoursePlan:
317
+ 'Dette faget følger en utgått læreplan. Gå til faget som er oppdatert etter gjeldende læreplan:',
318
+ updateBrowser:
319
+ 'Nettleseren din er utdatert. Oppdater den, eller finn en trygg og oppdatert nettleser på https://browsehappy.com.',
320
+ noContent: 'Vi har dessverre ikke noen programfag ennå.',
321
+ feide: 'Denne ressursen er bare tilgjengelig for lærere som er pålogget med Feide.',
322
+ resources:
323
+ 'Dette er ikke et komplett læremiddel produsert av NDLA, men ei ressurssamling som vi håper kan være nyttig for deg.',
324
+ beta: 'Dette faget er i betaversjon.',
325
+ outdatedSubject: 'Dette emnet hører til et fag som ikke er oppdatert etter gjeldende læreplan.',
326
+ newVersion:
327
+ 'Denne læringsressursen er ikke oppdatert etter gjeldende læreplan. Du finner en oppdatert versjon her: ',
328
+ },
315
329
  article: {
316
330
  lastUpdated: 'Sist oppdatert',
317
331
  edition: 'Utgave',
@@ -313,6 +313,20 @@ const messages = {
313
313
  h5p: 'Interaktiv',
314
314
  },
315
315
  },
316
+ messageBoxInfo: {
317
+ outdatedCoursePlan:
318
+ 'Dette faget følgjer ein utgått læreplan. Gå til faget som er oppdatert etter gjeldande læreplan: ',
319
+ updateBrowser:
320
+ 'Nettlesaren din er utdatert. Oppdater han, eller finn ein trygg og oppdatert nettlesar på https://browsehappy.com. ',
321
+ noContent: 'Vi har dessverre ikkje nokon programfag enno.',
322
+ feide: 'Denne ressursen er berre tilgjengeleg for lærarar som er pålogga med Feide.',
323
+ resources:
324
+ 'Dette er ikkje eit komplett læremiddel produsert av NDLA, men ei ressurssamling som vi håper kan vere nyttig for deg.',
325
+ beta: 'Dette faget er i betaversjon.',
326
+ outdatedSubject: 'Dette emnet høyrer til eit fag som ikkje er oppdatert etter gjeldande læreplan.',
327
+ newVersion:
328
+ 'Denne læringsressursen er ikkje oppdatert etter gjeldande læreplan. Du finn ein oppdatert versjon her: ',
329
+ },
316
330
  article: {
317
331
  lastUpdated: 'Sist oppdatert',
318
332
  edition: 'Utgåve',