@ndla/ui 25.0.1 → 25.2.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 (159) hide show
  1. package/es/Article/ArticleFavoritesButton.js +2 -1
  2. package/es/Frontpage/FrontpageHeader.js +7 -5
  3. package/es/Frontpage/FrontpageProgramMenu.js +12 -10
  4. package/es/Frontpage/FrontpageSearch.js +5 -3
  5. package/es/Image/Image.js +5 -4
  6. package/es/LanguageSelector/LanguageSelector.js +31 -26
  7. package/es/Masthead/Masthead.js +8 -8
  8. package/es/Masthead/MastheadAuthModal.js +11 -11
  9. package/es/Masthead/MastheadSearchModal.js +9 -11
  10. package/es/NDLAFilm/AboutNdlaFilm.js +3 -3
  11. package/es/NDLAFilm/FilmSlideshow.js +7 -7
  12. package/es/NDLAFilm/NavigationArrow.js +4 -4
  13. package/es/Navigation/NavigationHeading.js +9 -6
  14. package/es/Navigation/NavigationTopicAbout.js +15 -14
  15. package/es/Notion/FigureNotion.js +4 -3
  16. package/es/Notion/NotionVisualElement.js +3 -2
  17. package/es/Programme/Programme.js +10 -7
  18. package/es/Search/SearchField.js +4 -3
  19. package/es/Search/SearchFieldForm.js +4 -3
  20. package/es/Search/ToggleSearchButton.js +3 -3
  21. package/es/SectionHeading/SectionHeading.js +4 -3
  22. package/es/Subject/Subject.js +109 -64
  23. package/es/Subject/SubjectAbout.js +61 -23
  24. package/es/Subject/SubjectArchive.js +109 -67
  25. package/es/Subject/SubjectCarousel.js +39 -62
  26. package/es/Subject/SubjectHeader.js +55 -25
  27. package/es/Subject/SubjectLinks.js +30 -16
  28. package/es/Subject/SubjectNewContent.js +76 -21
  29. package/es/Subject/SubjectShortcuts.js +39 -24
  30. package/es/Subject/SubjectSocial.js +20 -18
  31. package/es/TagSelector/SuggestionInput.js +8 -8
  32. package/es/Topic/Topic.js +21 -20
  33. package/es/TopicMenu/TopicMenu.js +22 -13
  34. package/es/TopicMenu/TopicMenuButton.js +5 -5
  35. package/es/all.css +1 -1
  36. package/es/index.js +1 -0
  37. package/es/locale/messages-nb.js +23 -23
  38. package/es/locale/messages-nn.js +29 -29
  39. package/es/locale/messages-se.js +24 -24
  40. package/es/locale/messages-sma.js +24 -24
  41. package/lib/Article/ArticleFavoritesButton.js +2 -1
  42. package/lib/Frontpage/FrontpageHeader.js +7 -5
  43. package/lib/Frontpage/FrontpageMultidisciplinarySubject.d.ts +5 -5
  44. package/lib/Frontpage/FrontpageProgramMenu.js +12 -10
  45. package/lib/Frontpage/FrontpageSearch.js +6 -3
  46. package/lib/Frontpage/illustrations/FrontpageIllustrations.d.ts +2 -2
  47. package/lib/Image/Image.d.ts +1 -1
  48. package/lib/Image/Image.js +5 -4
  49. package/lib/LanguageSelector/LanguageSelector.d.ts +1 -1
  50. package/lib/LanguageSelector/LanguageSelector.js +31 -26
  51. package/lib/Masthead/Masthead.js +8 -8
  52. package/lib/Masthead/MastheadAuthModal.js +11 -11
  53. package/lib/Masthead/MastheadSearchModal.js +9 -11
  54. package/lib/MultidisciplinarySubject/Illustrations.d.ts +7 -7
  55. package/lib/NDLAFilm/AboutNdlaFilm.js +4 -4
  56. package/lib/NDLAFilm/FilmSlideshow.js +7 -7
  57. package/lib/NDLAFilm/NavigationArrow.js +4 -4
  58. package/lib/Navigation/NavigationHeading.d.ts +2 -1
  59. package/lib/Navigation/NavigationHeading.js +9 -6
  60. package/lib/Navigation/NavigationTopicAbout.js +15 -14
  61. package/lib/Notion/FigureNotion.d.ts +2 -1
  62. package/lib/Notion/FigureNotion.js +4 -3
  63. package/lib/Notion/NotionVisualElement.d.ts +1 -0
  64. package/lib/Notion/NotionVisualElement.js +3 -2
  65. package/lib/Programme/Programme.d.ts +2 -1
  66. package/lib/Programme/Programme.js +10 -7
  67. package/lib/Resource/resourceComponents.d.ts +2 -2
  68. package/lib/Search/ActiveFilterContent.d.ts +1 -1
  69. package/lib/Search/ContentTypeResultStyles.d.ts +3 -3
  70. package/lib/Search/SearchField.js +4 -3
  71. package/lib/Search/SearchFieldForm.js +4 -3
  72. package/lib/Search/ToggleSearchButton.js +3 -3
  73. package/lib/SearchTypeResult/ActiveFilterContent.d.ts +1 -1
  74. package/lib/SectionHeading/SectionHeading.js +4 -3
  75. package/lib/Subject/Subject.d.ts +30 -82
  76. package/lib/Subject/Subject.js +90 -62
  77. package/lib/Subject/SubjectAbout.d.ts +1 -15
  78. package/lib/Subject/SubjectAbout.js +56 -25
  79. package/lib/Subject/SubjectArchive.d.ts +0 -21
  80. package/lib/Subject/SubjectArchive.js +103 -73
  81. package/lib/Subject/SubjectCarousel.d.ts +1 -31
  82. package/lib/Subject/SubjectCarousel.js +47 -76
  83. package/lib/Subject/SubjectHeader.d.ts +1 -14
  84. package/lib/Subject/SubjectHeader.js +53 -28
  85. package/lib/Subject/SubjectLinks.d.ts +1 -11
  86. package/lib/Subject/SubjectLinks.js +29 -19
  87. package/lib/Subject/SubjectNewContent.d.ts +1 -13
  88. package/lib/Subject/SubjectNewContent.js +70 -24
  89. package/lib/Subject/SubjectShortcuts.d.ts +0 -13
  90. package/lib/Subject/SubjectShortcuts.js +38 -29
  91. package/lib/Subject/SubjectSocial.d.ts +7 -22
  92. package/lib/Subject/SubjectSocial.js +19 -21
  93. package/lib/TagSelector/SuggestionInput.js +8 -8
  94. package/lib/Topic/Topic.js +21 -20
  95. package/lib/TopicMenu/TopicMenu.js +47 -39
  96. package/lib/TopicMenu/TopicMenuButton.js +6 -6
  97. package/lib/all.css +1 -1
  98. package/lib/index.d.ts +1 -0
  99. package/lib/index.js +12 -3
  100. package/lib/locale/messages-nb.js +23 -23
  101. package/lib/locale/messages-nn.js +29 -29
  102. package/lib/locale/messages-se.js +24 -24
  103. package/lib/locale/messages-sma.js +24 -24
  104. package/package.json +14 -14
  105. package/src/Article/ArticleFavoritesButton.tsx +2 -1
  106. package/src/Frontpage/FrontpageHeader.tsx +1 -1
  107. package/src/Frontpage/FrontpageProgramMenu.tsx +1 -1
  108. package/src/Frontpage/FrontpageSearch.tsx +3 -1
  109. package/src/Image/Image.tsx +1 -1
  110. package/src/LanguageSelector/LanguageSelector.tsx +21 -23
  111. package/src/Masthead/Masthead.tsx +2 -0
  112. package/src/Masthead/MastheadAuthModal.tsx +16 -16
  113. package/src/Masthead/MastheadSearchModal.tsx +6 -23
  114. package/src/NDLAFilm/AboutNdlaFilm.tsx +2 -2
  115. package/src/NDLAFilm/FilmSlideshow.tsx +2 -0
  116. package/src/NDLAFilm/NavigationArrow.tsx +4 -4
  117. package/src/Navigation/NavigationHeading.tsx +3 -2
  118. package/src/Navigation/NavigationTopicAbout.tsx +1 -0
  119. package/src/Notion/FigureNotion.tsx +5 -2
  120. package/src/Notion/NotionVisualElement.tsx +2 -0
  121. package/src/Programme/Programme.tsx +11 -2
  122. package/src/Search/SearchField.tsx +6 -1
  123. package/src/Search/SearchFieldForm.tsx +1 -1
  124. package/src/Search/ToggleSearchButton.tsx +2 -2
  125. package/src/SectionHeading/SectionHeading.tsx +6 -2
  126. package/src/Subject/Subject.tsx +151 -72
  127. package/src/Subject/SubjectAbout.tsx +97 -27
  128. package/src/Subject/SubjectArchive.tsx +129 -58
  129. package/src/Subject/SubjectCarousel.tsx +42 -36
  130. package/src/Subject/SubjectHeader.tsx +75 -34
  131. package/src/Subject/SubjectLinks.tsx +21 -19
  132. package/src/Subject/SubjectNewContent.tsx +87 -32
  133. package/src/Subject/SubjectShortcuts.tsx +67 -27
  134. package/src/Subject/SubjectSocial.tsx +19 -20
  135. package/src/TagSelector/SuggestionInput.tsx +1 -1
  136. package/src/Topic/Topic.tsx +1 -0
  137. package/src/TopicMenu/TopicMenu.jsx +23 -17
  138. package/src/TopicMenu/TopicMenuButton.jsx +6 -7
  139. package/src/index.ts +2 -0
  140. package/src/locale/messages-nb.ts +22 -23
  141. package/src/locale/messages-nn.ts +28 -28
  142. package/src/locale/messages-se.ts +23 -24
  143. package/src/locale/messages-sma.ts +23 -24
  144. package/src/main.scss +0 -2
  145. package/es/Article/ArticleAuthorContent.js +0 -71
  146. package/lib/Article/ArticleAuthorContent.d.ts +0 -28
  147. package/lib/Article/ArticleAuthorContent.js +0 -88
  148. package/src/.DS_Store +0 -0
  149. package/src/Article/ArticleAuthorContent.tsx +0 -107
  150. package/src/Article/component.article-author-popup.scss +0 -90
  151. package/src/Subject/component.subject-about.scss +0 -73
  152. package/src/Subject/component.subject-archive.scss +0 -92
  153. package/src/Subject/component.subject-carousel.scss +0 -32
  154. package/src/Subject/component.subject-concepts.scss +0 -37
  155. package/src/Subject/component.subject-header.scss +0 -87
  156. package/src/Subject/component.subject-links.scss +0 -14
  157. package/src/Subject/component.subject-new-content.scss +0 -82
  158. package/src/Subject/component.subject-shortcut.scss +0 -57
  159. package/src/Subject/component.subject.scss +0 -213
@@ -1,15 +1,13 @@
1
1
  import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import BEMHelper from 'react-bem-helper';
2
+ import styled from '@emotion/styled';
3
+ import { css } from '@emotion/core';
4
4
  import { Carousel, CarouselAutosize } from '@ndla/carousel';
5
5
  import { withTranslation, WithTranslation } from 'react-i18next';
6
- import { spacingUnit } from '@ndla/core';
6
+ import { breakpoints, mq, spacing, spacingUnit } from '@ndla/core';
7
7
  import { SafeLinkProps } from '@ndla/safelink';
8
8
  import { ContentCard } from '../index';
9
9
  import { SubjectSectionTitle } from './Subject';
10
10
 
11
- const subjectCarouselClasses = BEMHelper('c-subject-carousel');
12
-
13
11
  interface Props {
14
12
  subjects?: {
15
13
  id: string;
@@ -24,11 +22,42 @@ interface Props {
24
22
  wideScreen?: boolean;
25
23
  }
26
24
 
27
- const getSubclasses = (obj: Record<string, boolean>): string[] => {
28
- return Object.entries(obj)
29
- .filter(([_, value]) => !!value)
30
- .map(([className, _]) => className);
31
- };
25
+ interface StyledSectionProps {
26
+ narrowScreen: boolean;
27
+ wideScreen: boolean;
28
+ }
29
+
30
+ const StyledSection = styled.section<StyledSectionProps>`
31
+ margin-bottom: ${spacing.large};
32
+ ${mq.range({ from: breakpoints.tablet })} {
33
+ margin-bottom: 100px;
34
+ }
35
+ ${(p) =>
36
+ p.narrowScreen &&
37
+ css`
38
+ display: none;
39
+ ${mq.range({ from: breakpoints.tablet })} {
40
+ display: block;
41
+ }
42
+ `};
43
+ ${(p) =>
44
+ p.narrowScreen &&
45
+ css`
46
+ ${mq.range({ from: breakpoints.tablet })} {
47
+ display: block;
48
+ }
49
+ `};
50
+ `;
51
+
52
+ const StyledSubjectSectionTitle = styled(SubjectSectionTitle)`
53
+ ${mq.range({ from: breakpoints.tablet })} {
54
+ margin-left: ${spacing.medium} !important;
55
+ }
56
+
57
+ ${mq.range({ from: breakpoints.desktop })} {
58
+ margin-left: ${spacingUnit * 3}px !important;
59
+ }
60
+ `;
32
61
 
33
62
  const SubjectCarousel = ({
34
63
  subjects = [],
@@ -37,7 +66,7 @@ const SubjectCarousel = ({
37
66
  wideScreen = false,
38
67
  t,
39
68
  }: Props & WithTranslation) => (
40
- <section {...subjectCarouselClasses('', getSubclasses({ narrowScreen, wideScreen }))}>
69
+ <StyledSection narrowScreen={narrowScreen} wideScreen={wideScreen}>
41
70
  <CarouselAutosize
42
71
  breakpoints={[
43
72
  {
@@ -99,7 +128,7 @@ const SubjectCarousel = ({
99
128
  itemsLength={subjects?.length ?? 0}>
100
129
  {(autoSizedProps) => (
101
130
  <>
102
- <SubjectSectionTitle {...subjectCarouselClasses('title')}>{title}</SubjectSectionTitle>
131
+ <StyledSubjectSectionTitle>{title}</StyledSubjectSectionTitle>
103
132
  <Carousel
104
133
  {...autoSizedProps}
105
134
  disableScroll={(autoSizedProps?.columnsPrSlide ?? 0) >= subjects.length}
@@ -122,30 +151,7 @@ const SubjectCarousel = ({
122
151
  </>
123
152
  )}
124
153
  </CarouselAutosize>
125
- </section>
154
+ </StyledSection>
126
155
  );
127
156
 
128
- SubjectCarousel.propTypes = {
129
- subjects: PropTypes.arrayOf(
130
- PropTypes.shape({
131
- id: PropTypes.string.isRequired,
132
- title: PropTypes.string.isRequired,
133
- type: PropTypes.string,
134
- text: PropTypes.string.isRequired,
135
- image: PropTypes.string,
136
- toLinkProps: PropTypes.func.isRequired,
137
- }).isRequired,
138
- ).isRequired,
139
- title: PropTypes.string,
140
- narrowScreen: PropTypes.bool,
141
- wideScreen: PropTypes.bool,
142
- };
143
-
144
- SubjectCarousel.defaultProps = {
145
- subjects: [],
146
- title: '',
147
- narrowScreen: false,
148
- wideScreen: false,
149
- };
150
-
151
157
  export default withTranslation()(SubjectCarousel);
@@ -1,13 +1,10 @@
1
1
  import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import BEMHelper from 'react-bem-helper';
4
-
2
+ import styled from '@emotion/styled';
3
+ import { css } from '@emotion/core';
5
4
  import { breakpoints } from '@ndla/util';
6
-
5
+ import { colors, fonts, mq, spacing, spacingUnit } from '@ndla/core';
7
6
  import OneColumn from '../Layout/OneColumn';
8
7
 
9
- const classes = BEMHelper('c-subject-header');
10
-
11
8
  type Types = 'mobile' | 'tablet' | 'desktop' | 'wide';
12
9
 
13
10
  interface Props {
@@ -18,36 +15,80 @@ interface Props {
18
15
  heading: string;
19
16
  }
20
17
 
21
- const SubjectHeader = ({ images, heading }: Props) => (
22
- <header {...classes()}>
23
- {images &&
24
- images.map((image) =>
25
- image.types.map((type) => (
26
- <div
27
- key={`${image.url}${type}`}
28
- {...classes('background', type)}
29
- style={{ backgroundImage: `url(${image.url})` }}
30
- />
31
- )),
32
- )}
33
- <OneColumn noPadding>
34
- <h1 {...classes('heading')}>{heading}</h1>
35
- </OneColumn>
36
- </header>
37
- );
18
+ const StyledHeader = styled.header`
19
+ width: 100%;
20
+ position: relative;
21
+ min-height: 180px;
22
+ display: flex;
23
+ justify-content: flex-start;
24
+ background: ${colors.brand.primary};
38
25
 
39
- SubjectHeader.propTypes = {
40
- images: PropTypes.arrayOf(
41
- PropTypes.shape({
42
- url: PropTypes.string.isRequired,
43
- types: PropTypes.arrayOf(PropTypes.oneOf(Object.keys(breakpoints))).isRequired,
44
- }),
45
- ),
46
- heading: PropTypes.string.isRequired,
47
- };
26
+ ${mq.range({ from: breakpoints.tablet })} {
27
+ height: 320px;
28
+ align-items: center;
29
+ }
30
+ `;
48
31
 
49
- SubjectHeader.defaultProps = {
50
- images: null,
32
+ const typeMap: Record<Types, { from?: string; until?: string }> = {
33
+ mobile: { from: breakpoints.mobile, until: breakpoints.tablet },
34
+ tablet: { from: breakpoints.tablet, until: breakpoints.desktop },
35
+ desktop: { from: breakpoints.desktop, until: breakpoints.wide },
36
+ wide: { from: breakpoints.wide },
51
37
  };
38
+ interface StyledBackgroundProps {
39
+ type: Types;
40
+ imageUrl: string;
41
+ }
42
+
43
+ const StyledBackground = styled.div<StyledBackgroundProps>`
44
+ position: absolute;
45
+ width: 100%;
46
+ height: 100%;
47
+ top: 0%;
48
+ background-size: cover;
49
+ background-repeat: no-repeat;
50
+ background-position: center right;
51
+ opacity: 0.5;
52
+ background-image: url(${(p) => p.imageUrl});
53
+ ${(p) =>
54
+ p.type &&
55
+ css`
56
+ display: none;
57
+ ${mq.range(typeMap[p.type])} {
58
+ display: block;
59
+ }
60
+ `};
61
+ `;
62
+
63
+ const StyledHeading = styled.h1`
64
+ ${fonts.sizes('24px', '28px')};
65
+ color: ${colors.white};
66
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.25);
67
+ margin: ${spacing.medium} 0 ${spacing.normal} 0;
68
+ font-weight: ${fonts.weight.bold};
69
+ padding: 0 ${spacing.normal};
70
+
71
+ ${mq.range({ from: breakpoints.tablet })} {
72
+ margin: 0;
73
+ ${fonts.sizes('40px', '40px')};
74
+ padding: 0 0 0 ${spacingUnit * 3}px;
75
+ }
76
+ ${mq.range({ from: breakpoints.desktop })} {
77
+ margin: 0;
78
+ ${fonts.sizes('52px', '52px')};
79
+ padding: 0 0 0 ${spacingUnit * 3}px;
80
+ }
81
+ `;
82
+
83
+ const SubjectHeader = ({ images = [], heading }: Props) => (
84
+ <StyledHeader>
85
+ {images?.map((image) =>
86
+ image.types.map((type) => <StyledBackground key={`${image.url}${type}`} imageUrl={image.url} type={type} />),
87
+ )}
88
+ <OneColumn noPadding>
89
+ <StyledHeading>{heading}</StyledHeading>
90
+ </OneColumn>
91
+ </StyledHeader>
92
+ );
52
93
 
53
94
  export default SubjectHeader;
@@ -1,11 +1,23 @@
1
1
  import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import BEMHelper from 'react-bem-helper';
2
+ import styled from '@emotion/styled';
3
+ import { spacing } from '@ndla/core';
4
4
  import SafeLink, { SafeLinkProps } from '@ndla/safelink';
5
5
 
6
6
  import { SubjectSectionTitle } from './Subject';
7
7
 
8
- const classes = BEMHelper('c-subject-links');
8
+ const SubjectLinksSection = styled.section`
9
+ margin-bottom: ${spacing.large};
10
+ `;
11
+
12
+ const StyledSubjectSectionTitle = styled(SubjectSectionTitle)`
13
+ margin: 0 0 ${spacing.small} 0;
14
+ `;
15
+
16
+ const SubjectLinksList = styled.ul`
17
+ margin: 0;
18
+ padding: 0;
19
+ list-style: none;
20
+ `;
9
21
 
10
22
  interface Props {
11
23
  links: {
@@ -16,28 +28,18 @@ interface Props {
16
28
  }
17
29
 
18
30
  const SubjectLinks = ({ links, heading }: Props) => (
19
- <section {...classes()}>
20
- <SubjectSectionTitle className={classes('heading').className}>{heading}</SubjectSectionTitle>
31
+ <SubjectLinksSection>
32
+ <StyledSubjectSectionTitle>{heading}</StyledSubjectSectionTitle>
21
33
  <nav>
22
- <ul {...classes('list')}>
34
+ <SubjectLinksList>
23
35
  {links.map((link) => (
24
- <li key={link.toLinkProps().to.toString()} {...classes('item')}>
36
+ <li key={link.toLinkProps().to.toString()}>
25
37
  <SafeLink {...link.toLinkProps()}>{link.text}</SafeLink>
26
38
  </li>
27
39
  ))}
28
- </ul>
40
+ </SubjectLinksList>
29
41
  </nav>
30
- </section>
42
+ </SubjectLinksSection>
31
43
  );
32
44
 
33
- SubjectLinks.propTypes = {
34
- links: PropTypes.arrayOf(
35
- PropTypes.shape({
36
- toLinkProps: PropTypes.func.isRequired,
37
- text: PropTypes.string.isRequired,
38
- }),
39
- ),
40
- heading: PropTypes.string.isRequired,
41
- };
42
-
43
45
  export default SubjectLinks;
@@ -1,12 +1,10 @@
1
1
  import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import BEMHelper from 'react-bem-helper';
2
+ import styled from '@emotion/styled';
4
3
  import SafeLink from '@ndla/safelink';
4
+ import { breakpoints, colors, fonts, mq, spacing } from '@ndla/core';
5
5
  import ContentTypeBadge from '../ContentTypeBadge';
6
6
  import { SubjectSectionTitle } from './Subject';
7
7
 
8
- const classes = BEMHelper('c-subject-new-content');
9
-
10
8
  interface Props {
11
9
  heading: string;
12
10
  content: {
@@ -17,39 +15,96 @@ interface Props {
17
15
  }[];
18
16
  }
19
17
 
18
+ const StyledSection = styled.section`
19
+ ${mq.range({ until: breakpoints.tablet })} {
20
+ margin-bottom: ${spacing.large};
21
+ }
22
+ `;
23
+
24
+ const StyledSubjectSectionTitle = styled(SubjectSectionTitle)`
25
+ ${mq.range({ from: breakpoints.tabletWide })} {
26
+ margin-left: ${spacing.large} !important;
27
+ }
28
+ `;
29
+
30
+ const StyledUl = styled.ul`
31
+ margin: 0;
32
+ padding: 0;
33
+ `;
34
+
35
+ const StyledListItem = styled.li`
36
+ display: flex;
37
+ align-items: center;
38
+ justify-content: space-between;
39
+ &:last-child {
40
+ margin-bottom: 0;
41
+ }
42
+ `;
43
+
44
+ const LeftWrapper = styled.div`
45
+ display: flex;
46
+ justify-content: flex-start;
47
+ align-items: flex-start;
48
+
49
+ .c-icon {
50
+ width: 14px;
51
+ height: 14px;
52
+ margin-left: ${spacing.xsmall};
53
+ margin-right: ${spacing.xsmall};
54
+ }
55
+
56
+ .c-content-type-badge {
57
+ margin-top: 23px;
58
+ ${mq.range({ until: breakpoints.tabletWide })} {
59
+ display: none;
60
+ }
61
+ }
62
+ `;
63
+
64
+ const ContentLinkWrapper = styled.div`
65
+ ${mq.range({ from: breakpoints.tabletWide })} {
66
+ padding-left: ${spacing.normal};
67
+ }
68
+ padding-bottom: ${spacing.small};
69
+ `;
70
+
71
+ const DateWrapper = styled.div`
72
+ color: ${colors.text.light};
73
+ ${fonts.sizes('14px', '18px')};
74
+ ${mq.range({ from: breakpoints.tablet })} {
75
+ ${fonts.sizes('16px', '20px')};
76
+ }
77
+ `;
78
+
79
+ const StyledSafeLink = styled(SafeLink)`
80
+ color: ${colors.brand.dark};
81
+ font-weight: 600;
82
+ ${fonts.sizes('16px', '20px')};
83
+ margin-bottom: ${spacing.xsmall};
84
+ ${mq.range({ from: breakpoints.tablet })} {
85
+ ${fonts.sizes('18px', '30px')};
86
+ }
87
+ `;
88
+
20
89
  const SubjectNewContent = ({ heading, content }: Props) => (
21
- <section {...classes()}>
22
- <SubjectSectionTitle className={classes('heading').className}>{heading}</SubjectSectionTitle>
23
- <nav {...classes('content')}>
24
- <ul {...classes('list')}>
90
+ <StyledSection>
91
+ <StyledSubjectSectionTitle>{heading}</StyledSubjectSectionTitle>
92
+ <nav>
93
+ <StyledUl>
25
94
  {content.map((item) => (
26
- <li {...classes('item')} key={item.url}>
27
- <div {...classes('left-wrapper')}>
95
+ <StyledListItem>
96
+ <LeftWrapper>
28
97
  <ContentTypeBadge type={item.contentType} size="x-small" background border />
29
- <div {...classes('content-link')}>
30
- <div {...classes('date')}>{item.formattedDate}</div>
31
- <SafeLink to={item.url} {...classes('link')}>
32
- {item.name}
33
- </SafeLink>
34
- </div>
35
- </div>
36
- </li>
98
+ <ContentLinkWrapper>
99
+ <DateWrapper>{item.formattedDate}</DateWrapper>
100
+ <StyledSafeLink to={item.url}>{item.name}</StyledSafeLink>
101
+ </ContentLinkWrapper>
102
+ </LeftWrapper>
103
+ </StyledListItem>
37
104
  ))}
38
- </ul>
105
+ </StyledUl>
39
106
  </nav>
40
- </section>
107
+ </StyledSection>
41
108
  );
42
109
 
43
- SubjectNewContent.propTypes = {
44
- heading: PropTypes.string.isRequired,
45
- content: PropTypes.arrayOf(
46
- PropTypes.shape({
47
- name: PropTypes.string.isRequired,
48
- url: PropTypes.string.isRequired,
49
- formattedDate: PropTypes.string.isRequired,
50
- contentType: PropTypes.string.isRequired,
51
- }),
52
- ).isRequired,
53
- };
54
-
55
110
  export default SubjectNewContent;
@@ -1,13 +1,68 @@
1
1
  import React, { Component } from 'react';
2
- import PropTypes from 'prop-types';
3
2
  import { TransitionGroup } from 'react-transition-group';
4
- import BEMHelper from 'react-bem-helper';
3
+ import styled from '@emotion/styled';
4
+ import { colors, fonts, spacing } from '@ndla/core';
5
5
  import { Forward } from '@ndla/icons/common';
6
6
  import SafeLink from '@ndla/safelink';
7
7
  import { SubjectSectionTitle } from './Subject';
8
8
  import Fade from '../Animation/Fade';
9
9
 
10
- const classes = BEMHelper('c-subject-shortcuts');
10
+ const SubjectShortcutsSection = styled.section`
11
+ margin-bottom: ${spacing.large};
12
+ `;
13
+
14
+ const StyledTransitionGroup = styled(TransitionGroup)`
15
+ display: flex;
16
+ flex-wrap: wrap;
17
+ list-style: none;
18
+ margin: 0;
19
+ padding: 0;
20
+ `;
21
+
22
+ const StyledListItem = styled.li`
23
+ display: block;
24
+ margin-right: 9px;
25
+ margin-bottom: 9px;
26
+
27
+ a {
28
+ display: block;
29
+ background: ${colors.brand.light};
30
+ box-shadow: none;
31
+ border-radius: 5px;
32
+ ${fonts.sizes('18px', '23px')};
33
+ font-weight: ${fonts.weight.semibold};
34
+ color: ${colors.brand.dark};
35
+ padding: 9px 20px;
36
+
37
+ &:hover,
38
+ &:active,
39
+ &:focus {
40
+ background-color: ${colors.brand.primary};
41
+ color: ${colors.white};
42
+ }
43
+ }
44
+ `;
45
+
46
+ const StyledButton = styled.button`
47
+ display: flex;
48
+ background: none;
49
+ border: 0;
50
+ align-items: center;
51
+ padding: 0;
52
+ color: ${colors.brand};
53
+ margin-top: ${spacing.normal};
54
+ cursor: pointer;
55
+
56
+ .c-icon {
57
+ width: 18px;
58
+ height: 18px;
59
+ margin-right: ${spacing.xsmall};
60
+ }
61
+
62
+ span {
63
+ ${fonts.sizes('14px', '18px')};
64
+ }
65
+ `;
11
66
 
12
67
  interface Props {
13
68
  links: {
@@ -59,51 +114,36 @@ class SubjectShortcuts extends Component<Props, State> {
59
114
  const buttonText = isExpanded ? messages.showLess : messages.showMore;
60
115
 
61
116
  button = (
62
- <button
117
+ <StyledButton
63
118
  type="button"
64
119
  aria-expanded={isExpanded}
65
120
  aria-controls={id}
66
- onClick={() => this.handleOnExpand(!isExpanded)}
67
- {...classes('expand-button')}>
121
+ onClick={() => this.handleOnExpand(!isExpanded)}>
68
122
  <Forward />
69
123
  <span>{buttonText}</span>
70
- </button>
124
+ </StyledButton>
71
125
  );
72
126
 
73
127
  filteredLinks = this.props.links.filter((link, index) => index < this.state.visibleCount);
74
128
  }
75
129
  return (
76
- <section {...classes('')}>
130
+ <SubjectShortcutsSection>
77
131
  <SubjectSectionTitle>{messages.heading}</SubjectSectionTitle>
78
132
  <nav id={id}>
79
- <TransitionGroup className={classes('list').className} component="ul">
133
+ <StyledTransitionGroup component="ul">
80
134
  {filteredLinks.map((link) => (
81
135
  <Fade key={link.url}>
82
- <li {...classes('item')}>
136
+ <StyledListItem>
83
137
  <SafeLink to={link.url}>{link.text}</SafeLink>
84
- </li>
138
+ </StyledListItem>
85
139
  </Fade>
86
140
  ))}
87
- </TransitionGroup>
141
+ </StyledTransitionGroup>
88
142
  </nav>
89
143
  {button}
90
- </section>
144
+ </SubjectShortcutsSection>
91
145
  );
92
146
  }
93
- static propTypes = {
94
- links: PropTypes.arrayOf(
95
- PropTypes.shape({
96
- url: PropTypes.string.isRequired,
97
- text: PropTypes.string.isRequired,
98
- }),
99
- ).isRequired,
100
- messages: PropTypes.shape({
101
- heading: PropTypes.string.isRequired,
102
- showMore: PropTypes.string.isRequired,
103
- showLess: PropTypes.string.isRequired,
104
- }).isRequired,
105
- defaultVisableCount: PropTypes.number,
106
- };
107
147
 
108
148
  static defaultProps = {
109
149
  defaultVisableCount,
@@ -1,30 +1,29 @@
1
+ import styled from '@emotion/styled';
2
+ import { breakpoints, mq, spacing } from '@ndla/core';
1
3
  import React, { ReactNode } from 'react';
2
- import PropTypes from 'prop-types';
3
- import BEMHelper from 'react-bem-helper';
4
4
  import { SubjectSectionTitle } from './Subject';
5
5
 
6
- const classes = BEMHelper('c-subject-social');
6
+ const StyledSubjectSocialContent = styled.div`
7
+ display: none;
8
+ ${mq.range({ from: breakpoints.tabletWide })} {
9
+ display: flex;
10
+ }
11
+ `;
7
12
 
8
13
  export const SubjectSocialContent = ({ children }: { children: ReactNode }) => (
9
- <div {...classes('content')}>{children}</div>
14
+ <StyledSubjectSocialContent>{children}</StyledSubjectSocialContent>
10
15
  );
11
16
 
12
- SubjectSocialContent.propTypes = {
13
- children: PropTypes.node.isRequired,
14
- };
17
+ const StyledSection = styled.section`
18
+ flex-basis: 50%;
19
+ &:nth-child(odd) {
20
+ margin-right: ${spacing.normal};
21
+ }
22
+ `;
15
23
 
16
- export const SubjectSocialSection = ({ children, title }: { children: ReactNode; title?: string }) => (
17
- <section {...classes('section')}>
18
- <SubjectSectionTitle className={classes('title').className}>{title}</SubjectSectionTitle>
24
+ export const SubjectSocialSection = ({ children, title = '' }: { children: ReactNode; title?: string }) => (
25
+ <StyledSection>
26
+ <SubjectSectionTitle>{title}</SubjectSectionTitle>
19
27
  {children}
20
- </section>
28
+ </StyledSection>
21
29
  );
22
-
23
- SubjectSocialSection.propTypes = {
24
- children: PropTypes.node.isRequired,
25
- title: PropTypes.string,
26
- };
27
-
28
- SubjectSocialSection.defaultProps = {
29
- title: '',
30
- };
@@ -254,7 +254,7 @@ const SuggestionInput = ({
254
254
  ariaLabelActive={t('tagSelector.showAllTags')}
255
255
  ariaLabelInActive={t('tagSelector.hideAllTags')}
256
256
  active={expanded}
257
- greyLighter
257
+ colorTheme="lighter"
258
258
  inactiveIcon={<ChevronDown />}
259
259
  activeIcon={<ChevronUp />}
260
260
  size="small"
@@ -339,6 +339,7 @@ const Topic = ({
339
339
  {onToggleShowContent && (
340
340
  <StyledButtonWrapper invertedStyle={invertedStyle}>
341
341
  <Button
342
+ aria-expanded={!!showContent}
342
343
  link
343
344
  onClick={() => {
344
345
  onToggleShowContent();