@ndla/ui 22.2.0 → 24.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 (166) hide show
  1. package/es/Animation/DisplayOnPageYOffset.js +1 -1
  2. package/es/Article/Article.js +3 -3
  3. package/es/Article/ArticleAuthorContent.js +2 -4
  4. package/es/Article/ArticleByline.js +5 -6
  5. package/es/AuthorInfo/AuthorInfo.js +29 -16
  6. package/es/Breadcrumb/ActionBreadcrumb.js +3 -3
  7. package/es/ContentCard/ContentCard.js +66 -25
  8. package/es/Figure/FigureOpenDialogButton.js +1 -2
  9. package/es/FileList/File.js +34 -8
  10. package/es/FileList/FileList.js +29 -3
  11. package/es/Filter/FilterListPhone.js +1 -1
  12. package/es/Frontpage/FrontpageProgramMenu.js +10 -11
  13. package/es/InfoBox/InfoBox.js +10 -3
  14. package/es/InfoWidget/InfoWidget.js +67 -22
  15. package/es/NDLAFilm/AllMoviesAlphabetically.js +12 -12
  16. package/es/Portrait/Portrait.js +19 -13
  17. package/es/ResourceBox/ResourceBox.js +7 -35
  18. package/es/ResourceGroup/ResourceItem.js +13 -13
  19. package/es/ResourceGroup/ResourceList.js +3 -3
  20. package/es/Search/ActiveFilterContent.js +4 -14
  21. package/es/Search/ActiveFilters.js +20 -31
  22. package/es/Search/SearchField.js +31 -52
  23. package/es/Search/SearchResult.js +113 -136
  24. package/es/Search/ToggleSearchButton.js +34 -43
  25. package/es/Search/index.js +2 -8
  26. package/es/SearchTypeResult/ActiveFilters.js +18 -18
  27. package/es/SearchTypeResult/SearchFieldHeader.js +5 -6
  28. package/es/TopicMenu/TopicMenu.js +1 -1
  29. package/es/all.css +1 -1
  30. package/es/index-javascript.js +0 -1
  31. package/es/index.js +2 -1
  32. package/es/locale/messages-en.js +2 -0
  33. package/es/locale/messages-nb.js +2 -0
  34. package/es/locale/messages-nn.js +2 -0
  35. package/es/locale/messages-se.js +2 -0
  36. package/es/locale/messages-sma.js +2 -0
  37. package/lib/Animation/DisplayOnPageYOffset.js +2 -2
  38. package/lib/Article/Article.js +4 -4
  39. package/lib/Article/ArticleAuthorContent.js +9 -4
  40. package/lib/Article/ArticleByline.js +4 -4
  41. package/lib/AuthorInfo/AuthorInfo.d.ts +1 -11
  42. package/lib/AuthorInfo/AuthorInfo.js +36 -20
  43. package/lib/Breadcrumb/ActionBreadcrumb.js +3 -3
  44. package/lib/ContentCard/ContentCard.d.ts +1 -15
  45. package/lib/ContentCard/ContentCard.js +60 -28
  46. package/lib/FileList/File.js +36 -12
  47. package/lib/FileList/FileList.js +28 -5
  48. package/lib/Filter/FilterListPhone.js +2 -2
  49. package/lib/Frontpage/FrontpageProgramMenu.js +9 -9
  50. package/lib/InfoBox/InfoBox.js +11 -4
  51. package/lib/InfoWidget/InfoWidget.js +61 -25
  52. package/lib/NDLAFilm/AllMoviesAlphabetically.js +13 -13
  53. package/lib/Portrait/Portrait.js +19 -14
  54. package/lib/ResourceBox/ResourceBox.d.ts +1 -4
  55. package/lib/ResourceBox/ResourceBox.js +15 -35
  56. package/lib/ResourceGroup/ResourceItem.js +12 -14
  57. package/lib/ResourceGroup/ResourceList.js +2 -4
  58. package/lib/Search/ActiveFilterContent.d.ts +13 -0
  59. package/lib/Search/ActiveFilterContent.js +4 -15
  60. package/lib/Search/ActiveFilters.d.ts +13 -0
  61. package/lib/Search/ActiveFilters.js +31 -45
  62. package/lib/Search/SearchField.d.ts +19 -0
  63. package/lib/Search/SearchField.js +32 -56
  64. package/lib/Search/SearchResult.d.ts +36 -0
  65. package/lib/Search/SearchResult.js +116 -159
  66. package/lib/Search/ToggleSearchButton.d.ts +16 -0
  67. package/lib/Search/ToggleSearchButton.js +36 -46
  68. package/lib/Search/index.d.ts +12 -0
  69. package/lib/Search/index.js +0 -54
  70. package/lib/SearchTypeResult/ActiveFilters.js +37 -39
  71. package/lib/SearchTypeResult/SearchFieldHeader.js +6 -6
  72. package/lib/SearchTypeResult/SearchTypeHeader.d.ts +1 -1
  73. package/lib/TopicMenu/TopicMenu.js +2 -2
  74. package/lib/all.css +1 -1
  75. package/lib/index-javascript.js +0 -74
  76. package/lib/index.d.ts +1 -0
  77. package/lib/index.js +38 -1
  78. package/lib/locale/messages-en.d.ts +2 -0
  79. package/lib/locale/messages-en.js +2 -0
  80. package/lib/locale/messages-nb.d.ts +2 -0
  81. package/lib/locale/messages-nb.js +2 -0
  82. package/lib/locale/messages-nn.d.ts +2 -0
  83. package/lib/locale/messages-nn.js +2 -0
  84. package/lib/locale/messages-se.d.ts +2 -0
  85. package/lib/locale/messages-se.js +2 -0
  86. package/lib/locale/messages-sma.d.ts +2 -0
  87. package/lib/locale/messages-sma.js +2 -0
  88. package/package.json +17 -16
  89. package/src/Animation/DisplayOnPageYOffset.tsx +1 -1
  90. package/src/Article/Article.tsx +1 -1
  91. package/src/Article/ArticleAuthorContent.tsx +1 -1
  92. package/src/Article/ArticleByline.tsx +1 -2
  93. package/src/AuthorInfo/AuthorInfo.tsx +53 -19
  94. package/src/Breadcrumb/ActionBreadcrumb.tsx +1 -2
  95. package/src/ContentCard/ContentCard.tsx +127 -35
  96. package/src/Figure/FigureOpenDialogButton.tsx +1 -2
  97. package/src/FileList/File.tsx +47 -17
  98. package/src/FileList/FileList.tsx +37 -8
  99. package/src/Filter/FilterListPhone.jsx +1 -1
  100. package/src/Frontpage/FrontpageProgramMenu.tsx +1 -2
  101. package/src/InfoBox/InfoBox.tsx +24 -4
  102. package/src/InfoWidget/InfoWidget.tsx +83 -34
  103. package/src/NDLAFilm/AllMoviesAlphabetically.tsx +1 -1
  104. package/src/Portrait/Portrait.tsx +25 -10
  105. package/src/ResourceBox/ResourceBox.tsx +1 -20
  106. package/src/ResourceGroup/ResourceItem.tsx +1 -1
  107. package/src/ResourceGroup/ResourceList.tsx +1 -1
  108. package/src/Search/{ActiveFilterContent.jsx → ActiveFilterContent.tsx} +11 -12
  109. package/src/Search/{ActiveFilters.jsx → ActiveFilters.tsx} +21 -18
  110. package/src/Search/{SearchField.jsx → SearchField.tsx} +58 -68
  111. package/src/Search/SearchResult.tsx +360 -0
  112. package/src/Search/ToggleSearchButton.tsx +73 -0
  113. package/src/Search/component.search.scss +0 -4
  114. package/src/Search/index.ts +16 -0
  115. package/src/SearchTypeResult/ActiveFilters.tsx +1 -1
  116. package/src/SearchTypeResult/SearchFieldHeader.tsx +1 -2
  117. package/src/TopicMenu/TopicMenu.jsx +1 -1
  118. package/src/all.scss +0 -1
  119. package/src/index-javascript.js +0 -15
  120. package/src/index.ts +2 -0
  121. package/src/locale/messages-en.ts +2 -0
  122. package/src/locale/messages-nb.ts +2 -0
  123. package/src/locale/messages-nn.ts +2 -0
  124. package/src/locale/messages-se.ts +2 -0
  125. package/src/locale/messages-sma.ts +2 -0
  126. package/src/main.scss +0 -7
  127. package/es/BackgroundImage/BackgroundImage.js +0 -27
  128. package/es/BackgroundImage/index.js +0 -2
  129. package/es/Search/SearchFilter.js +0 -72
  130. package/es/Search/SearchFilterList.js +0 -115
  131. package/es/Search/SearchOverlay.js +0 -39
  132. package/es/Search/SearchPage.js +0 -178
  133. package/es/Search/SearchPopoverFilter.js +0 -152
  134. package/es/Search/SearchResultAuthor.js +0 -51
  135. package/lib/BackgroundImage/BackgroundImage.d.ts +0 -12
  136. package/lib/BackgroundImage/BackgroundImage.js +0 -40
  137. package/lib/BackgroundImage/index.d.ts +0 -2
  138. package/lib/BackgroundImage/index.js +0 -13
  139. package/lib/Search/SearchFilter.js +0 -88
  140. package/lib/Search/SearchFilterList.js +0 -137
  141. package/lib/Search/SearchOverlay.js +0 -62
  142. package/lib/Search/SearchPage.js +0 -207
  143. package/lib/Search/SearchPopoverFilter.js +0 -172
  144. package/lib/Search/SearchResultAuthor.js +0 -60
  145. package/src/AuthorInfo/component.author-info.scss +0 -54
  146. package/src/BackgroundImage/BackgroundImage.tsx +0 -32
  147. package/src/BackgroundImage/component.background-image.scss +0 -52
  148. package/src/BackgroundImage/index.ts +0 -3
  149. package/src/ContentCard/component.content-card.scss +0 -109
  150. package/src/FileList/component.file-list.scss +0 -102
  151. package/src/InfoBox/component.info-box.scss +0 -21
  152. package/src/InfoWidget/component.info-widget.scss +0 -52
  153. package/src/Portrait/component.portrait.scss +0 -29
  154. package/src/Search/SearchFilter.jsx +0 -82
  155. package/src/Search/SearchFilterList.jsx +0 -110
  156. package/src/Search/SearchOverlay.jsx +0 -38
  157. package/src/Search/SearchPage.jsx +0 -178
  158. package/src/Search/SearchPopoverFilter.jsx +0 -109
  159. package/src/Search/SearchResult.jsx +0 -239
  160. package/src/Search/SearchResultAuthor.jsx +0 -54
  161. package/src/Search/ToggleSearchButton.jsx +0 -64
  162. package/src/Search/component.search-filter.scss +0 -67
  163. package/src/Search/component.search-overlay.scss +0 -103
  164. package/src/Search/component.search-page.scss +0 -125
  165. package/src/Search/component.search-result-author.scss +0 -65
  166. package/src/Search/index.js +0 -34
@@ -1,11 +1,36 @@
1
+ import styled from '@emotion/styled';
2
+ import { breakpoints, colors, fonts, mq, spacing } from '@ndla/core';
1
3
  import { Download } from '@ndla/icons/common';
2
4
  import SafeLink from '@ndla/safelink';
3
5
  import Tooltip from '@ndla/tooltip';
4
6
  import React from 'react';
5
- import BEMHelper from 'react-bem-helper';
6
7
  import { FileFormat, FileType } from './FileList';
7
8
 
8
- const classes = BEMHelper('c-file-list');
9
+ const LinkText = styled.span`
10
+ & > span {
11
+ box-shadow: inset 0 -1px;
12
+ }
13
+ `;
14
+ const FileLink = styled(SafeLink)`
15
+ box-shadow: none;
16
+ position: relative;
17
+ color: ${colors.brand.primary};
18
+ margin-right: ${spacing.normal};
19
+ display: flex;
20
+ align-items: center;
21
+
22
+ &:last-child {
23
+ margin-right: 0;
24
+ }
25
+
26
+ &:hover,
27
+ &:focus,
28
+ &:active {
29
+ ${LinkText} {
30
+ box-shadow: none;
31
+ }
32
+ }
33
+ `;
9
34
 
10
35
  const renderFormat = (format: FileFormat, title: string, isPrimary: boolean, id: string, isDeadLink: boolean) => {
11
36
  const titleWithFormat = `${title} (${format.fileType.toUpperCase()})`;
@@ -22,20 +47,14 @@ const renderFormat = (format: FileFormat, title: string, isPrimary: boolean, id:
22
47
  }
23
48
 
24
49
  return (
25
- <SafeLink
26
- {...classes('link')}
27
- key={format.url}
28
- to={format.url}
29
- target="_blank"
30
- aria-label={titleWithFormat}
31
- aria-describedby={formatId}>
50
+ <FileLink key={format.url} to={format.url} target="_blank" aria-label={titleWithFormat} aria-describedby={formatId}>
32
51
  <Download />
33
52
  <Tooltip tooltip={format.tooltip}>
34
- <span {...classes('link-text')}>
53
+ <LinkText>
35
54
  <span>{isPrimary ? titleWithFormat : `(${format.fileType.toUpperCase()})`}</span>
36
- </span>
55
+ </LinkText>
37
56
  </Tooltip>
38
- </SafeLink>
57
+ </FileLink>
39
58
  );
40
59
  };
41
60
 
@@ -44,16 +63,27 @@ interface Props {
44
63
  file: FileType;
45
64
  }
46
65
 
66
+ const FileListItem = styled.li`
67
+ ${fonts.sizes('18px', '26px')};
68
+ font-weight: ${fonts.weight.semibold};
69
+ min-height: 60px;
70
+ background: ${colors.brand.greyLighter};
71
+ display: flex;
72
+ align-items: center;
73
+ flex-wrap: wrap;
74
+ margin-bottom: ${spacing.xsmall};
75
+ padding: ${spacing.small};
76
+ ${mq.range({ from: breakpoints.tablet })} {
77
+ padding: ${spacing.small} ${spacing.normal};
78
+ }
79
+ `;
80
+
47
81
  const File = ({ file, id }: Props) => {
48
82
  const formatLinks = file.formats.map((format, index) =>
49
83
  renderFormat(format, file.title, index === 0, id, !file.fileExists),
50
84
  );
51
85
 
52
- return (
53
- <li {...classes('item')} key={file.title}>
54
- {formatLinks}
55
- </li>
56
- );
86
+ return <FileListItem key={file.title}>{formatLinks}</FileListItem>;
57
87
  };
58
88
 
59
89
  export default File;
@@ -1,9 +1,8 @@
1
1
  import React from 'react';
2
- import BEMHelper from 'react-bem-helper';
2
+ import styled from '@emotion/styled';
3
+ import { colors, fonts, spacing } from '@ndla/core';
3
4
  import File from './File';
4
5
 
5
- const classes = BEMHelper('c-file-list');
6
-
7
6
  export interface FileType {
8
7
  title: string;
9
8
  formats: FileFormat[];
@@ -22,15 +21,45 @@ interface Props {
22
21
  files: FileType[];
23
22
  }
24
23
 
24
+ const FileListSection = styled.section`
25
+ margin: ${spacing.large} 0;
26
+ padding: ${spacing.small} 0 ${spacing.normal} ${spacing.normal};
27
+ border-left: 2px solid ${colors.brand.greyLightest};
28
+ font-family: ${fonts.sans};
29
+
30
+ .c-icon {
31
+ margin-top: 3px;
32
+ flex-shrink: 0;
33
+ margin-right: ${spacing.small};
34
+ height: 18px;
35
+ width: 18px;
36
+ }
37
+ `;
38
+
39
+ const FileListHeading = styled.h1`
40
+ ${fonts.sizes('16px', '18px')};
41
+ letter-spacing: 0.05em;
42
+ margin: 0 0 ${spacing.xsmall} 0;
43
+ padding-bottom: ${spacing.xsmall};
44
+ border-bottom: 2px solid ${colors.brand.greyLight};
45
+ font-weight: ${fonts.weight.bold};
46
+ text-transform: uppercase;
47
+ `;
48
+
49
+ const FilesList = styled.ul`
50
+ margin: 0;
51
+ padding: 0;
52
+ `;
53
+
25
54
  const FileList = ({ files, heading, id }: Props) => (
26
- <section {...classes()}>
27
- <h1 {...classes('heading')}>{heading}</h1>
28
- <ul {...classes('files')}>
55
+ <FileListSection>
56
+ <FileListHeading>{heading}</FileListHeading>
57
+ <FilesList>
29
58
  {files.map((file) => (
30
59
  <File key={`file-${id}-${file.title}`} file={file} id={id} />
31
60
  ))}
32
- </ul>
33
- </section>
61
+ </FilesList>
62
+ </FileListSection>
34
63
  );
35
64
 
36
65
  export default FileList;
@@ -12,7 +12,7 @@ import { ChevronDown, ChevronUp } from '@ndla/icons/common';
12
12
  import { Cross } from '@ndla/icons/action';
13
13
  import Modal, { ModalHeader, ModalBody, ModalCloseButton } from '@ndla/modal';
14
14
  import Button from '@ndla/button';
15
- import debounce from 'lodash/debounce';
15
+ import { debounce } from 'lodash';
16
16
  import { classes } from './filterClasses';
17
17
  import ToggleItem from './ToggleItem';
18
18
  import ActiveFilters from '../Search/ActiveFilters';
@@ -1,8 +1,7 @@
1
1
  import React, { useEffect, useState } from 'react';
2
2
  import styled from '@emotion/styled';
3
3
  import Button from '@ndla/button';
4
- import { fonts } from '@ndla/core';
5
- import { breakpoints, mq } from '@ndla/core';
4
+ import { fonts, breakpoints, mq } from '@ndla/core';
6
5
  import { useTranslation } from 'react-i18next';
7
6
  import NavigationBox, { ItemProps } from '../Navigation/NavigationBox';
8
7
  import FrontpageAllSubjects, { subjectsProps } from './FrontpageAllSubjects';
@@ -1,11 +1,31 @@
1
+ import styled from '@emotion/styled';
2
+ import { breakpoints, colors, fonts, mq, spacing } from '@ndla/core/src';
1
3
  import React, { ReactNode } from 'react';
2
- import BEMHelper from 'react-bem-helper';
3
-
4
- const classes = BEMHelper('c-info-box');
5
4
 
6
5
  interface Props {
7
6
  children?: ReactNode;
8
7
  }
9
- const InfoBox = ({ children }: Props) => <div {...classes()}>{children}</div>;
8
+
9
+ const StyledInfoBox = styled.div`
10
+ background: ${colors.support.yellowLight};
11
+ padding: ${spacing.small} ${spacing.normal};
12
+ font-family: ${fonts.sans};
13
+ ${fonts.sizes('14px', '18px')};
14
+ margin-bottom: ${spacing.medium};
15
+ ${mq.range({ from: breakpoints.tablet })} {
16
+ ${fonts.sizes('16px', '20px')};
17
+ padding: ${spacing.normal};
18
+ }
19
+
20
+ & > *:first-child {
21
+ margin-top: 0;
22
+ }
23
+
24
+ & > *:last-child {
25
+ margin-bottom: 0;
26
+ }
27
+ `;
28
+
29
+ const InfoBox = ({ children }: Props) => <StyledInfoBox>{children}</StyledInfoBox>;
10
30
 
11
31
  export default InfoBox;
@@ -1,13 +1,67 @@
1
+ import styled from '@emotion/styled';
2
+ import { css } from '@emotion/core';
1
3
  import React, { ReactNode } from 'react';
2
- import BEMHelper from 'react-bem-helper';
3
4
  import { Forward } from '@ndla/icons/common';
4
-
5
5
  import SafeLink from '@ndla/safelink';
6
+ import { colors, fonts, spacing } from '@ndla/core';
6
7
 
7
8
  import SectionHeading from '../SectionHeading';
8
9
 
9
- const classes = BEMHelper('c-info-widget');
10
+ interface InfoWidgetSectionProps {
11
+ center?: boolean;
12
+ }
13
+ const InfoWidgetSection = styled.section<InfoWidgetSectionProps>`
14
+ max-width: 600px;
15
+ margin: ${(p) => p.center && '0 auto'};
16
+ `;
17
+
18
+ const InfoWidgetDescription = styled.div`
19
+ padding: ${spacing.normal};
20
+ background: ${colors.brand.lighter};
21
+ color: ${colors.brand.dark};
22
+ ${fonts.sizes('18px', '26px')};
23
+
24
+ p {
25
+ margin-top: 0;
26
+ &:last-child {
27
+ margin-bottom: 0;
28
+ }
29
+ }
30
+ `;
31
+
32
+ const InfoWidgetLinksContainer = styled.div`
33
+ display: flex;
34
+ align-items: center;
35
+ justify-content: flex-end;
36
+ `;
37
+
38
+ const iconLinkStyle = css`
39
+ width: 47px;
40
+ height: 47px;
41
+ border-radius: 100%;
42
+ background: ${colors.brand.lighter};
43
+ color: ${colors.brand.dark};
44
+ box-shadow: none;
45
+ display: flex;
46
+ justify-content: center;
47
+ align-items: center;
48
+ margin-right: ${spacing.small};
10
49
 
50
+ .c-icon {
51
+ width: 20px;
52
+ height: 20px;
53
+ }
54
+ `;
55
+
56
+ const IconSafeLink = styled(SafeLink)(iconLinkStyle);
57
+
58
+ const IconAnchor = styled.a(iconLinkStyle);
59
+ const IconSpan = styled.span(iconLinkStyle);
60
+
61
+ const StyledMainLink = styled.a`
62
+ color: ${colors.brand.dark};
63
+ ${fonts.sizes('16px', '24px')};
64
+ `;
11
65
  interface Props {
12
66
  heading: string;
13
67
  description: string;
@@ -26,36 +80,33 @@ interface Props {
26
80
  }
27
81
 
28
82
  const InfoWidget = ({ heading, description, mainLink, iconLinks, center = false }: Props) => (
29
- <section {...classes('', { center })}>
30
- <SectionHeading large className={classes('heading').className}>
31
- {heading}
32
- </SectionHeading>
33
- <div {...classes('description')}>
83
+ <InfoWidgetSection center={center}>
84
+ <SectionHeading large>{heading}</SectionHeading>
85
+ <InfoWidgetDescription>
34
86
  <p>{description}</p>
35
- </div>
36
- <div {...classes('links')}>
37
- {iconLinks &&
38
- iconLinks.map((link) => {
39
- if (link.url) {
40
- return (
41
- <SafeLink key={link.url} {...classes('icon-link')} to={link.url} aria-label={link.name}>
42
- {link.icon}
43
- </SafeLink>
44
- );
45
- }
46
- if (link.href) {
47
- return (
48
- <a key={link.href} href={link.href} {...classes('icon-link')} aria-label={link.name}>
49
- {link.icon}
50
- </a>
51
- );
52
- }
87
+ </InfoWidgetDescription>
88
+ <InfoWidgetLinksContainer>
89
+ {iconLinks?.map((link) => {
90
+ if (link.url) {
91
+ return (
92
+ <IconSafeLink key={link.url} to={link.url} aria-label={link.name}>
93
+ {link.icon}
94
+ </IconSafeLink>
95
+ );
96
+ }
97
+ if (link.href) {
53
98
  return (
54
- <span key={link.name} {...classes('icon-link')} aria-label={link.name}>
99
+ <IconAnchor key={link.href} href={link.href} aria-label={link.name}>
55
100
  {link.icon}
56
- </span>
101
+ </IconAnchor>
57
102
  );
58
- })}
103
+ }
104
+ return (
105
+ <IconSpan key={link.name} aria-label={link.name}>
106
+ {link.icon}
107
+ </IconSpan>
108
+ );
109
+ })}
59
110
  {mainLink.url ? (
60
111
  <div className="o-text-link__wrapper o-text-link__wrapper--right">
61
112
  <SafeLink className="o-text-link" to={mainLink.url}>
@@ -63,12 +114,10 @@ const InfoWidget = ({ heading, description, mainLink, iconLinks, center = false
63
114
  </SafeLink>
64
115
  </div>
65
116
  ) : (
66
- <a {...classes('main-link')} href={mainLink.href}>
67
- {mainLink.name}
68
- </a>
117
+ <StyledMainLink href={mainLink.href}>{mainLink.name}</StyledMainLink>
69
118
  )}
70
- </div>
71
- </section>
119
+ </InfoWidgetLinksContainer>
120
+ </InfoWidgetSection>
72
121
  );
73
122
 
74
123
  export default InfoWidget;
@@ -10,7 +10,7 @@ import React, { Fragment, RefObject, useEffect, useRef, useState } from 'react';
10
10
  import { isIE, browserVersion } from 'react-device-detect';
11
11
  import styled from '@emotion/styled';
12
12
  import { css } from '@emotion/core';
13
- import throttle from 'lodash/throttle';
13
+ import { throttle } from 'lodash';
14
14
  import { breakpoints, mq, spacing, spacingUnit, colors, fonts, animations } from '@ndla/core';
15
15
  import SafeLink from '@ndla/safelink';
16
16
  import { makeSrcQueryString } from '../Image';
@@ -6,13 +6,25 @@
6
6
  *
7
7
  */
8
8
 
9
+ import styled from '@emotion/styled';
9
10
  import React from 'react';
10
- import BEMHelper from 'react-bem-helper';
11
11
 
12
- const classes = new BEMHelper({
13
- name: 'portrait',
14
- prefix: 'c-',
15
- });
12
+ interface PortraitWrapperProps {
13
+ size: string;
14
+ }
15
+ const PortraitWrapper = styled.div<PortraitWrapperProps>`
16
+ width: ${(p) => p.size};
17
+ height: ${(p) => p.size};
18
+ span {
19
+ display: block;
20
+ border-radius: 50%;
21
+ background-color: rgba(0, 0, 0, 0.16);
22
+ background-size: cover;
23
+ background-position: center center;
24
+ width: ${(p) => p.size};
25
+ height: ${(p) => p.size};
26
+ }
27
+ `;
16
28
 
17
29
  interface Props {
18
30
  src: string;
@@ -21,10 +33,13 @@ interface Props {
21
33
  modifier?: 'small' | 'large';
22
34
  }
23
35
 
24
- const Portrait = ({ src, alt, modifier, className }: Props) => (
25
- <div {...classes('', modifier, className)}>
26
- <span role="img" aria-label={alt} style={{ backgroundImage: `url(${src})` }} />
27
- </div>
28
- );
36
+ const Portrait = ({ src, alt, modifier, className }: Props) => {
37
+ const size = modifier === 'small' ? '4rem' : modifier === 'large' ? '10rem' : '7rem';
38
+ return (
39
+ <PortraitWrapper size={size} className={className}>
40
+ <span role="img" aria-label={alt} style={{ backgroundImage: `url(${src})` }} />
41
+ </PortraitWrapper>
42
+ );
43
+ };
29
44
 
30
45
  export default Portrait;
@@ -10,7 +10,6 @@ import React from 'react';
10
10
  import { breakpoints, fonts, mq, colors, spacing } from '@ndla/core';
11
11
  import { useTranslation } from 'react-i18next';
12
12
  import { Launch } from '@ndla/icons/common';
13
- import { LicenseByline } from '@ndla/licenses';
14
13
  import { SafeLinkButton } from '@ndla/safelink';
15
14
  import styled from '@emotion/styled';
16
15
  import Image from '../Image';
@@ -81,12 +80,6 @@ const StyledImage = styled(Image)`
81
80
  }
82
81
  `;
83
82
 
84
- const LincenseWrapper = styled.div`
85
- position: absolute;
86
- top: 9px;
87
- right: 0;
88
- `;
89
-
90
83
  interface ImageMeta {
91
84
  src: string;
92
85
  alt: string;
@@ -96,25 +89,13 @@ interface Props {
96
89
  image: ImageMeta;
97
90
  title: string;
98
91
  caption: string;
99
- licenseRights: string[];
100
- authors?: string[];
101
- locale?: string;
102
92
  url: string;
103
93
  }
104
94
 
105
- export const ResourceBox = ({ image, title, caption, licenseRights, locale, authors, url }: Props) => {
95
+ export const ResourceBox = ({ image, title, caption, url }: Props) => {
106
96
  const { t } = useTranslation();
107
97
  return (
108
98
  <ResourceBoxContainer>
109
- <LincenseWrapper>
110
- <LicenseByline licenseRights={licenseRights} locale={locale} marginRight color={colors.brand.tertiary}>
111
- {authors && authors.length > 0 && (
112
- <div className="c-figure__byline-author-buttons">
113
- <span className="c-figure__byline-authors">{authors.join(' ')}</span>
114
- </div>
115
- )}
116
- </LicenseByline>
117
- </LincenseWrapper>
118
99
  <StyledImage src={image.src} alt={image.alt} />
119
100
  <ContentWrapper>
120
101
  <Title>{title}</Title>
@@ -9,7 +9,7 @@
9
9
  import React from 'react';
10
10
  import { useTranslation } from 'react-i18next';
11
11
  import styled from '@emotion/styled';
12
- import css from '@emotion/css';
12
+ import { css } from '@emotion/core';
13
13
  import { keyframes } from '@emotion/core';
14
14
  import SafeLink from '@ndla/safelink';
15
15
  import { Additional, Core, HumanMaleBoard } from '@ndla/icons/common';
@@ -8,7 +8,7 @@
8
8
 
9
9
  import React from 'react';
10
10
  import styled from '@emotion/styled';
11
- import css from '@emotion/css';
11
+ import { css } from '@emotion/core';
12
12
  import { keyframes } from '@emotion/core';
13
13
  import { useTranslation } from 'react-i18next';
14
14
  import NoContentBox from '../NoContentBox';
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
- import PropTypes from 'prop-types';
3
2
  import styled from '@emotion/styled';
4
3
  import { Cross } from '@ndla/icons/action';
5
4
  import { spacing, mq, breakpoints, colors, misc, fonts } from '@ndla/core';
@@ -32,7 +31,17 @@ export const StyledActiveFilterTitle = styled('span')`
32
31
  padding-right: ${spacing.small};
33
32
  `;
34
33
 
35
- const ActiveFilterContent = ({ filter, onFilterRemove, ariaLabel }) => (
34
+ interface Props {
35
+ filter: {
36
+ value: string;
37
+ title: string;
38
+ filterName?: string;
39
+ };
40
+ onFilterRemove: (value: string, filterName?: string) => void;
41
+ ariaLabel: string;
42
+ }
43
+
44
+ const ActiveFilterContent = ({ filter, onFilterRemove, ariaLabel }: Props) => (
36
45
  <StyledActiveFilter
37
46
  aria-label={ariaLabel}
38
47
  type="button"
@@ -42,14 +51,4 @@ const ActiveFilterContent = ({ filter, onFilterRemove, ariaLabel }) => (
42
51
  </StyledActiveFilter>
43
52
  );
44
53
 
45
- ActiveFilterContent.propTypes = {
46
- filter: PropTypes.shape({
47
- value: PropTypes.string.isRequired,
48
- title: PropTypes.string.isRequired,
49
- filterName: PropTypes.string,
50
- }),
51
- onFilterRemove: PropTypes.func.isRequired,
52
- ariaLabel: PropTypes.string.isRequired,
53
- };
54
-
55
54
  export default ActiveFilterContent;
@@ -1,13 +1,17 @@
1
1
  import React from 'react';
2
- import PropTypes from 'prop-types';
3
2
  import styled from '@emotion/styled';
4
- import css from '@emotion/css';
3
+ import { css } from '@emotion/core';
5
4
  import { spacing, mq, breakpoints } from '@ndla/core';
6
5
  import Tooltip from '@ndla/tooltip';
7
6
  import { useTranslation } from 'react-i18next';
8
7
  import ActiveFilterContent, { StyledActiveFilterTitle } from './ActiveFilterContent';
9
8
 
10
- const StyledActiveFilters = styled('ul')`
9
+ interface StyledActiveFiltersProps {
10
+ showOnSmallScreen?: boolean;
11
+ filterLength?: number;
12
+ }
13
+
14
+ const StyledActiveFilters = styled('ul')<StyledActiveFiltersProps>`
11
15
  margin: 0;
12
16
  padding: 0;
13
17
  flex-direction: column;
@@ -70,10 +74,22 @@ const StyledActiveFilterWrapper = styled('li')`
70
74
  }
71
75
  `;
72
76
 
73
- const getFilterLength = (filters) =>
77
+ const getFilterLength = (filters: Filter[]) =>
74
78
  filters.filter((filter) => filter.filterName === 'filter_subjects' && filter.title).length;
75
79
 
76
- const ActiveFilters = ({ filters, onFilterRemove, showOnSmallScreen }) => {
80
+ interface Filter {
81
+ title: string;
82
+ value: string;
83
+ filterName?: string;
84
+ }
85
+
86
+ interface Props {
87
+ filters: Filter[];
88
+ onFilterRemove: (value: string, filterName?: string) => void;
89
+ showOnSmallScreen?: boolean;
90
+ }
91
+
92
+ const ActiveFilters = ({ filters, onFilterRemove, showOnSmallScreen }: Props) => {
77
93
  const { t } = useTranslation();
78
94
  if (filters && filters.length > 0) {
79
95
  const filterLength = getFilterLength(filters);
@@ -90,7 +106,6 @@ const ActiveFilters = ({ filters, onFilterRemove, showOnSmallScreen }) => {
90
106
  })}>
91
107
  <ActiveFilterContent
92
108
  filter={filter}
93
- filterLength={filterLength}
94
109
  ariaLabel={t('searchPage.searchFilterMessages.removeFilter', {
95
110
  filterName: filter.title,
96
111
  })}
@@ -100,7 +115,6 @@ const ActiveFilters = ({ filters, onFilterRemove, showOnSmallScreen }) => {
100
115
  ) : (
101
116
  <ActiveFilterContent
102
117
  filter={filter}
103
- filterLength={filterLength}
104
118
  onFilterRemove={onFilterRemove}
105
119
  ariaLabel={t('searchPage.searchFilterMessages.removeFilter', {
106
120
  filterName: filter.title,
@@ -121,15 +135,4 @@ const ActiveFilters = ({ filters, onFilterRemove, showOnSmallScreen }) => {
121
135
  return null;
122
136
  };
123
137
 
124
- ActiveFilters.propTypes = {
125
- filters: PropTypes.arrayOf(
126
- PropTypes.shape({
127
- value: PropTypes.string.isRequired,
128
- title: PropTypes.string.isRequired,
129
- filterName: PropTypes.string,
130
- }),
131
- ),
132
- onFilterRemove: PropTypes.func.isRequired,
133
- };
134
-
135
138
  export default ActiveFilters;