@ndla/ui 50.5.4 → 50.6.1

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 (60) hide show
  1. package/es/CompetenceGoalTab/SearchButton.js +3 -3
  2. package/es/ErrorMessage/ErrorResourceAccessDenied.js +3 -3
  3. package/es/FileList/File.js +9 -55
  4. package/es/FileList/FileList.js +19 -8
  5. package/es/FileList/Format.js +70 -0
  6. package/es/FileList/index.js +1 -0
  7. package/es/LearningPaths/LearningPathSticky.js +6 -8
  8. package/es/LicenseByline/EmbedByline.js +7 -7
  9. package/es/Navigation/NavigationBox.js +43 -78
  10. package/es/ResourceGroup/ResourceItem.js +15 -11
  11. package/es/Search/ContentTypeResult.js +3 -3
  12. package/es/Search/SearchResult.js +11 -11
  13. package/es/Search/SearchResultSleeve.js +11 -11
  14. package/es/SearchTypeResult/components/ItemContexts.js +9 -7
  15. package/es/Topic/Topic.js +24 -52
  16. package/es/all.css +1 -1
  17. package/es/index.js +1 -1
  18. package/lib/CompetenceGoalTab/SearchButton.js +3 -3
  19. package/lib/ErrorMessage/ErrorResourceAccessDenied.js +3 -3
  20. package/lib/FileList/File.js +11 -54
  21. package/lib/FileList/FileList.d.ts +4 -3
  22. package/lib/FileList/FileList.js +19 -8
  23. package/lib/FileList/Format.d.ts +16 -0
  24. package/lib/FileList/Format.js +74 -0
  25. package/lib/FileList/index.d.ts +1 -0
  26. package/lib/FileList/index.js +7 -0
  27. package/lib/LearningPaths/LearningPathSticky.js +6 -8
  28. package/lib/LicenseByline/EmbedByline.js +7 -7
  29. package/lib/Navigation/NavigationBox.d.ts +2 -5
  30. package/lib/Navigation/NavigationBox.js +42 -77
  31. package/lib/ResourceGroup/ResourceItem.js +15 -11
  32. package/lib/Search/ContentTypeResult.js +3 -3
  33. package/lib/Search/SearchResult.js +11 -11
  34. package/lib/Search/SearchResultSleeve.js +11 -11
  35. package/lib/SearchTypeResult/components/ItemContexts.js +9 -7
  36. package/lib/Topic/Topic.js +24 -50
  37. package/lib/all.css +1 -1
  38. package/lib/index.d.ts +1 -1
  39. package/lib/index.js +6 -0
  40. package/package.json +17 -17
  41. package/src/CompetenceGoalTab/SearchButton.tsx +1 -1
  42. package/src/ErrorMessage/ErrorResourceAccessDenied.tsx +2 -2
  43. package/src/Figure/component.figure.scss +5 -2
  44. package/src/FileList/File.tsx +5 -65
  45. package/src/FileList/FileList.tsx +18 -13
  46. package/src/FileList/Format.tsx +75 -0
  47. package/src/FileList/index.ts +1 -0
  48. package/src/Filter/component.filter.scss +1 -1
  49. package/src/LearningPaths/LearningPathSticky.tsx +2 -15
  50. package/src/LicenseByline/EmbedByline.tsx +2 -1
  51. package/src/Navigation/NavigationBox.tsx +76 -104
  52. package/src/ResourceGroup/ResourceItem.tsx +2 -2
  53. package/src/Search/ContentTypeResult.tsx +2 -2
  54. package/src/Search/SearchResult.tsx +3 -3
  55. package/src/Search/SearchResultSleeve.tsx +3 -3
  56. package/src/Search/component.search-result.scss +1 -1
  57. package/src/SearchTypeResult/components/ItemContexts.tsx +5 -1
  58. package/src/Topic/Topic.tsx +26 -39
  59. package/src/all.scss +0 -1
  60. package/src/index.ts +1 -1
package/lib/index.d.ts CHANGED
@@ -18,7 +18,7 @@ export { default as Masthead, getMastheadHeight, useMastheadHeight, SkipToMainCo
18
18
  export { default as ContentLoader } from './ContentLoader';
19
19
  export { default as RelatedArticleList, RelatedArticle } from './RelatedArticleList';
20
20
  export { ErrorResourceAccessDenied, default as ErrorMessage } from './ErrorMessage';
21
- export { default as FileList, File, PdfFile } from './FileList';
21
+ export { default as FileList, File, PdfFile, Format } from './FileList';
22
22
  export { default as Logo } from './Logo';
23
23
  export { default as FactBox } from './FactBox';
24
24
  export { default as Image, ImageLink, makeSrcQueryString } from './Image';
package/lib/index.js CHANGED
@@ -381,6 +381,12 @@ Object.defineProperty(exports, "FootnoteEmbed", {
381
381
  return _Embed.FootnoteEmbed;
382
382
  }
383
383
  });
384
+ Object.defineProperty(exports, "Format", {
385
+ enumerable: true,
386
+ get: function () {
387
+ return _FileList.Format;
388
+ }
389
+ });
384
390
  Object.defineProperty(exports, "FramedContent", {
385
391
  enumerable: true,
386
392
  get: function () {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ndla/ui",
3
- "version": "50.5.4",
3
+ "version": "50.6.1",
4
4
  "description": "UI component library for NDLA.",
5
5
  "license": "GPL-3.0",
6
6
  "main": "lib/index.js",
@@ -31,23 +31,23 @@
31
31
  "types"
32
32
  ],
33
33
  "dependencies": {
34
- "@ndla/accordion": "^3.0.13",
35
- "@ndla/button": "^12.0.18",
36
- "@ndla/carousel": "^4.0.19",
37
- "@ndla/core": "^4.3.0",
38
- "@ndla/dropdown-menu": "^1.0.20",
39
- "@ndla/forms": "^5.2.8",
34
+ "@ndla/accordion": "^3.0.15",
35
+ "@ndla/button": "^12.0.20",
36
+ "@ndla/carousel": "^4.0.21",
37
+ "@ndla/core": "^4.3.1",
38
+ "@ndla/dropdown-menu": "^1.0.21",
39
+ "@ndla/forms": "^5.2.10",
40
40
  "@ndla/hooks": "^2.1.4",
41
- "@ndla/icons": "^4.2.5",
41
+ "@ndla/icons": "^5.0.0",
42
42
  "@ndla/licenses": "^7.2.4",
43
- "@ndla/modal": "^5.0.18",
44
- "@ndla/notion": "^6.0.19",
45
- "@ndla/safelink": "^4.1.43",
46
- "@ndla/select": "^3.2.5",
47
- "@ndla/switch": "^1.1.26",
48
- "@ndla/tabs": "^3.2.6",
49
- "@ndla/tooltip": "^6.0.8",
50
- "@ndla/typography": "^0.4.3",
43
+ "@ndla/modal": "^5.0.20",
44
+ "@ndla/notion": "^6.0.21",
45
+ "@ndla/safelink": "^4.1.45",
46
+ "@ndla/select": "^3.2.7",
47
+ "@ndla/switch": "^1.1.27",
48
+ "@ndla/tabs": "^3.2.7",
49
+ "@ndla/tooltip": "^6.0.9",
50
+ "@ndla/typography": "^0.4.4",
51
51
  "@ndla/util": "^4.0.3",
52
52
  "@radix-ui/react-popover": "^1.0.7",
53
53
  "@radix-ui/react-slider": "^1.1.2",
@@ -81,5 +81,5 @@
81
81
  "publishConfig": {
82
82
  "access": "public"
83
83
  },
84
- "gitHead": "674b17d155fc4c43b541e179821826bea1d47327"
84
+ "gitHead": "e7999bc4ea44f44a2138566150480fe6c285522f"
85
85
  }
@@ -41,7 +41,7 @@ const SearchButton = ({ url, isOembed, searchText }: SearchButtonProps) => {
41
41
  return (
42
42
  <GoalSearchWrapper>
43
43
  <SafeLinkButton variant="outline" to={url} target={isOembed ? '_blank' : '_self'}>
44
- <StyledSearch size="24" />
44
+ <StyledSearch size="normal" />
45
45
  <span>{searchText}</span>
46
46
  </SafeLinkButton>
47
47
  </GoalSearchWrapper>
@@ -30,12 +30,12 @@ const ErrorResourceAccessDenied = ({ onAuthenticateClick }: Props) => {
30
30
  back: t('errorMessage.back'),
31
31
  goToFrontPage: t('errorMessage.goToFrontPage'),
32
32
  }}
33
- illustrationElement={<HumanMaleBoard className="c-icon--large" />}
33
+ illustrationElement={<HumanMaleBoard size="large" />}
34
34
  customElement={
35
35
  <ButtonV2 size="medium" onClick={onAuthenticateClick}>
36
36
  {t('user.buttonLogIn')}
37
37
  <StyledLogInIconWrapper aria-hidden>
38
- <LogIn className="c-icon--medium" />
38
+ <LogIn size="normal" />
39
39
  </StyledLogInIconWrapper>
40
40
  </ButtonV2>
41
41
  }
@@ -37,7 +37,10 @@
37
37
  margin: $spacing 0 $spacing;
38
38
  position: relative;
39
39
  width: 100%;
40
- transition: transform 0.4s, width 0.4s, height 0.4s;
40
+ transition:
41
+ transform 0.4s,
42
+ width 0.4s,
43
+ height 0.4s;
41
44
 
42
45
  &--full-column {
43
46
  left: auto !important;
@@ -235,7 +238,7 @@
235
238
  &__link-wrapper {
236
239
  margin-top: $spacing--small;
237
240
 
238
- .c-icon {
241
+ [data-icon] {
239
242
  margin-left: $spacing--small/2;
240
243
  width: 18px;
241
244
  height: 18px;
@@ -8,9 +8,8 @@
8
8
 
9
9
  import { useTranslation } from 'react-i18next';
10
10
  import styled from '@emotion/styled';
11
- import { breakpoints, colors, fonts, mq, spacing } from '@ndla/core';
12
- import { Download } from '@ndla/icons/common';
13
- import SafeLink from '@ndla/safelink';
11
+ import { breakpoints, colors, mq, spacing } from '@ndla/core';
12
+ import Format from './Format';
14
13
 
15
14
  interface Props {
16
15
  title: string;
@@ -18,7 +17,6 @@ interface Props {
18
17
  fileExists: boolean;
19
18
  fileType: string;
20
19
  }
21
-
22
20
  export interface FileType {
23
21
  title: string;
24
22
  formats: FileFormat[];
@@ -31,36 +29,7 @@ export interface FileFormat {
31
29
  tooltip: string;
32
30
  }
33
31
 
34
- const LinkTextWrapper = styled.div`
35
- & > span {
36
- box-shadow: inset 0 -1px;
37
- }
38
- `;
39
- const FileLink = styled(SafeLink)`
40
- box-shadow: none;
41
- position: relative;
42
- color: ${colors.brand.primary};
43
- margin-right: ${spacing.normal};
44
- display: flex;
45
- align-items: center;
46
-
47
- &:last-child {
48
- margin-right: 0;
49
- }
50
-
51
- &:hover,
52
- &:focus,
53
- &:active {
54
- ${LinkTextWrapper} {
55
- box-shadow: none;
56
- }
57
- }
58
- `;
59
-
60
- const FileListItem = styled.li`
61
- ${fonts.sizes('18px', '26px')};
62
- font-weight: ${fonts.weight.semibold};
63
- min-height: 60px;
32
+ const StyledFileItem = styled.li`
64
33
  background: ${colors.brand.greyLighter};
65
34
  display: flex;
66
35
  align-items: center;
@@ -72,43 +41,14 @@ const FileListItem = styled.li`
72
41
  }
73
42
  `;
74
43
 
75
- interface FormatProps {
76
- format: FileFormat;
77
- title: string;
78
- isPrimary: boolean;
79
- isDeadLink: boolean;
80
- }
81
-
82
- const Format = ({ format, title, isPrimary, isDeadLink }: FormatProps) => {
83
- const titleWithFormat = `${title} (${format.fileType.toUpperCase()})`;
84
-
85
- if (isDeadLink) {
86
- return (
87
- <span key={format.url}>
88
- <Download />
89
- <span>{isPrimary ? titleWithFormat : `(${format.fileType.toUpperCase()})`}</span>
90
- </span>
91
- );
92
- }
93
-
94
- return (
95
- <FileLink key={format.url} to={format.url} target="_blank" aria-label={titleWithFormat}>
96
- <Download />
97
- <LinkTextWrapper aria-label={format.tooltip}>
98
- <span>{isPrimary ? titleWithFormat : `(${format.fileType.toUpperCase()})`}</span>
99
- </LinkTextWrapper>
100
- </FileLink>
101
- );
102
- };
103
-
104
44
  const File = ({ title, url, fileExists, fileType }: Props) => {
105
45
  const { t } = useTranslation();
106
46
  const tooltip = `${t('download')} ${url.split('/').pop()}`;
107
47
 
108
48
  return (
109
- <FileListItem>
49
+ <StyledFileItem>
110
50
  <Format format={{ url, fileType, tooltip }} isPrimary title={title} isDeadLink={!fileExists} />
111
- </FileListItem>
51
+ </StyledFileItem>
112
52
  );
113
53
  };
114
54
 
@@ -6,22 +6,23 @@
6
6
  *
7
7
  */
8
8
 
9
- import { ReactNode } from 'react';
9
+ import { ComponentProps, ReactNode } from 'react';
10
10
  import { useTranslation } from 'react-i18next';
11
11
  import styled from '@emotion/styled';
12
12
  import { colors, fonts, spacing } from '@ndla/core';
13
-
14
- interface Props {
13
+ import { Heading } from '@ndla/typography';
14
+ interface Props extends ComponentProps<'section'> {
15
15
  children: ReactNode;
16
+ headingButtons?: ReactNode;
16
17
  }
17
18
 
18
19
  const FileListSection = styled.section`
19
20
  margin: ${spacing.large} 0;
20
- padding: ${spacing.small} 0 ${spacing.normal} ${spacing.normal};
21
+ padding: 0 0 ${spacing.normal} ${spacing.normal};
21
22
  border-left: 2px solid ${colors.brand.greyLightest};
22
23
  font-family: ${fonts.sans};
23
24
 
24
- .c-icon {
25
+ [data-icon] {
25
26
  margin-top: 3px;
26
27
  flex-shrink: 0;
27
28
  margin-right: ${spacing.small};
@@ -30,14 +31,13 @@ const FileListSection = styled.section`
30
31
  }
31
32
  `;
32
33
 
33
- const FileListHeading = styled.h3`
34
- ${fonts.sizes('16px', '18px')};
35
- letter-spacing: 0.05em;
34
+ const FileListHeaderWrapper = styled.div`
35
+ display: flex;
36
+ justify-content: space-between;
37
+ align-items: center;
36
38
  margin: 0 0 ${spacing.xsmall} 0;
37
39
  padding-bottom: ${spacing.xsmall};
38
40
  border-bottom: 2px solid ${colors.brand.greyLight};
39
- font-weight: ${fonts.weight.bold};
40
- text-transform: uppercase;
41
41
  `;
42
42
 
43
43
  const FilesList = styled.ul`
@@ -45,11 +45,16 @@ const FilesList = styled.ul`
45
45
  padding: 0;
46
46
  `;
47
47
 
48
- const FileList = ({ children }: Props) => {
48
+ const FileList = ({ children, headingButtons, ...rest }: Props) => {
49
49
  const { t } = useTranslation();
50
50
  return (
51
- <FileListSection>
52
- <FileListHeading>{t('files')}</FileListHeading>
51
+ <FileListSection {...rest}>
52
+ <FileListHeaderWrapper>
53
+ <Heading element="h3" headingStyle="list-title" margin="none">
54
+ {t('files')}
55
+ </Heading>
56
+ <div>{headingButtons}</div>
57
+ </FileListHeaderWrapper>
53
58
  <FilesList>{children}</FilesList>
54
59
  </FileListSection>
55
60
  );
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Copyright (c) 2023-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import styled from '@emotion/styled';
10
+ import { colors, spacing } from '@ndla/core';
11
+ import { Download } from '@ndla/icons/common';
12
+ import SafeLink from '@ndla/safelink';
13
+ import { Text } from '@ndla/typography';
14
+ import { FileFormat } from './File';
15
+
16
+ const StyledText = styled(Text)`
17
+ box-shadow: inset 0 -1px;
18
+
19
+ &:hover,
20
+ &:focus,
21
+ &:active {
22
+ box-shadow: none;
23
+ }
24
+ `;
25
+
26
+ const FileLink = styled(SafeLink)`
27
+ box-shadow: none;
28
+ position: relative;
29
+ color: ${colors.brand.primary};
30
+ display: flex;
31
+ align-items: center;
32
+ `;
33
+
34
+ const StyledDownload = styled(Download)`
35
+ margin-top: 3px;
36
+ flex-shrink: 0;
37
+ margin-right: ${spacing.small};
38
+ height: 18px;
39
+ width: 18px;
40
+ `;
41
+
42
+ interface FormatProps {
43
+ format: FileFormat;
44
+ title: string;
45
+ isPrimary: boolean;
46
+ isDeadLink: boolean;
47
+ }
48
+
49
+ const Format = ({ format, title, isPrimary, isDeadLink }: FormatProps) => {
50
+ const titleWithFormat = `${title} (${format.fileType.toUpperCase()})`;
51
+
52
+ if (isDeadLink) {
53
+ return (
54
+ <span key={format.url}>
55
+ <StyledDownload />
56
+ <Text element="span" textStyle="label-small" margin="none">
57
+ {isPrimary ? titleWithFormat : `(${format.fileType.toUpperCase()})`}
58
+ </Text>
59
+ </span>
60
+ );
61
+ }
62
+
63
+ return (
64
+ <FileLink key={format.url} to={format.url} target="_blank" aria-label={titleWithFormat}>
65
+ <StyledDownload />
66
+ <div aria-label={format.tooltip}>
67
+ <StyledText element="span" textStyle="label-small" margin="none">
68
+ {isPrimary ? titleWithFormat : `(${format.fileType.toUpperCase()})`}
69
+ </StyledText>
70
+ </div>
71
+ </FileLink>
72
+ );
73
+ };
74
+
75
+ export default Format;
@@ -10,5 +10,6 @@ import FileList from './FileList';
10
10
 
11
11
  export { default as File } from './File';
12
12
  export { default as PdfFile } from './PdfFile';
13
+ export { default as Format } from './Format';
13
14
 
14
15
  export default FileList;
@@ -292,7 +292,7 @@
292
292
  }
293
293
  }
294
294
 
295
- .c-icon {
295
+ [data-icon] {
296
296
  margin-left: $spacing--small;
297
297
  }
298
298
 
@@ -63,9 +63,6 @@ const SafeLinkCSS = css`
63
63
  padding: 0;
64
64
  }
65
65
  transition: background 200ms ease;
66
- > .c-icon--medium {
67
- transition: transform 200ms ease;
68
- }
69
66
  div {
70
67
  display: flex;
71
68
  flex-direction: column;
@@ -88,16 +85,6 @@ const SafeLinkCSS = css`
88
85
  box-shadow: none;
89
86
  }
90
87
  }
91
- ${mq.range({ from: breakpoints.tablet })} {
92
- > .c-icon--medium {
93
- transform: translateX(${spacing.xsmall});
94
- }
95
- &:first-of-type {
96
- > .c-icon--medium {
97
- transform: translateX(-${spacing.xsmall});
98
- }
99
- }
100
- }
101
88
  }
102
89
  `;
103
90
 
@@ -123,11 +110,11 @@ export const LearningPathStickySibling = ({ title, toLearningPathUrl, pathId, st
123
110
  css={SafeLinkCSS}
124
111
  aria-label={arrow === 'left' ? t('learningPath.previousArrow') : t('learningPath.nextArrow')}
125
112
  >
126
- {arrow === 'left' && <Back className="c-icon--medium" />}
113
+ {arrow === 'left' && <Back size="normal" />}
127
114
  <div>
128
115
  <StyledTitle>{title}</StyledTitle>
129
116
  </div>
130
- {arrow === 'right' && <Forward className="c-icon--medium" />}
117
+ {arrow === 'right' && <Forward size="normal" />}
131
118
  </SafeLink>
132
119
  );
133
120
  };
@@ -106,6 +106,7 @@ const mobileStyling = css`
106
106
  const RightsWrapper = styled.div`
107
107
  display: flex;
108
108
  align-items: center;
109
+ flex-wrap: wrap;
109
110
  gap: ${spacing.nsmall};
110
111
 
111
112
  &[data-grid='true'] {
@@ -163,7 +164,7 @@ const EmbedByline = ({
163
164
  {license ? <LicenseLink license={license} asLink={!!license.url.length} /> : null}
164
165
  <LicenseInformationWrapper>
165
166
  <span>
166
- <b>{t(`embed.type.${type}`)}: </b>
167
+ <b>{`${t(`embed.type.${type}`)}${captionAuthors.length ? ':' : ''}`} </b>
167
168
  {captionAuthors.map((author) => author.name).join(', ')}
168
169
  </span>
169
170
  </LicenseInformationWrapper>