@ndla/ui 50.5.3 → 50.6.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 (51) hide show
  1. package/es/FileList/File.js +9 -55
  2. package/es/FileList/FileList.js +19 -8
  3. package/es/FileList/Format.js +70 -0
  4. package/es/FileList/index.js +1 -0
  5. package/es/LicenseByline/EmbedByline.js +7 -7
  6. package/es/Navigation/NavigationBox.js +43 -78
  7. package/es/ResourceGroup/ResourceItem.js +15 -11
  8. package/es/SearchTypeResult/components/ItemContexts.js +9 -7
  9. package/es/Topic/Topic.js +24 -52
  10. package/es/all.css +1 -1
  11. package/es/index.js +1 -1
  12. package/es/locale/messages-en.js +1 -1
  13. package/es/locale/messages-nb.js +1 -1
  14. package/es/locale/messages-nn.js +1 -1
  15. package/es/locale/messages-sma.js +1 -1
  16. package/lib/FileList/File.js +11 -54
  17. package/lib/FileList/FileList.d.ts +4 -3
  18. package/lib/FileList/FileList.js +19 -8
  19. package/lib/FileList/Format.d.ts +16 -0
  20. package/lib/FileList/Format.js +74 -0
  21. package/lib/FileList/index.d.ts +1 -0
  22. package/lib/FileList/index.js +7 -0
  23. package/lib/LicenseByline/EmbedByline.js +7 -7
  24. package/lib/Navigation/NavigationBox.d.ts +2 -5
  25. package/lib/Navigation/NavigationBox.js +42 -77
  26. package/lib/ResourceGroup/ResourceItem.js +15 -11
  27. package/lib/SearchTypeResult/components/ItemContexts.js +9 -7
  28. package/lib/Topic/Topic.js +24 -50
  29. package/lib/all.css +1 -1
  30. package/lib/index.d.ts +1 -1
  31. package/lib/index.js +6 -0
  32. package/lib/locale/messages-en.js +1 -1
  33. package/lib/locale/messages-nb.js +1 -1
  34. package/lib/locale/messages-nn.js +1 -1
  35. package/lib/locale/messages-sma.js +1 -1
  36. package/package.json +12 -12
  37. package/src/FileList/File.tsx +5 -65
  38. package/src/FileList/FileList.tsx +17 -20
  39. package/src/FileList/Format.tsx +75 -0
  40. package/src/FileList/index.ts +1 -0
  41. package/src/LicenseByline/EmbedByline.tsx +2 -1
  42. package/src/Navigation/NavigationBox.tsx +76 -104
  43. package/src/ResourceGroup/ResourceItem.tsx +2 -2
  44. package/src/SearchTypeResult/components/ItemContexts.tsx +5 -1
  45. package/src/Topic/Topic.tsx +26 -39
  46. package/src/all.scss +0 -1
  47. package/src/index.ts +1 -1
  48. package/src/locale/messages-en.ts +1 -1
  49. package/src/locale/messages-nb.ts +1 -1
  50. package/src/locale/messages-nn.ts +1 -1
  51. package/src/locale/messages-sma.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 () {
@@ -1130,7 +1130,7 @@ const messages = {
1130
1130
  recentArenaTopics: 'New posts in the arena'
1131
1131
  },
1132
1132
  myProfile: {
1133
- title: 'My Profile',
1133
+ title: 'My profile',
1134
1134
  disclaimerTitle: {
1135
1135
  employee: 'Where is my name used?',
1136
1136
  student: 'Where is my name used?'
@@ -1130,7 +1130,7 @@ const messages = {
1130
1130
  recentArenaTopics: 'Nye innlegg i arenaen'
1131
1131
  },
1132
1132
  myProfile: {
1133
- title: 'Min Profil',
1133
+ title: 'Min profil',
1134
1134
  disclaimerTitle: {
1135
1135
  employee: 'Hvor brukes navnet mitt?',
1136
1136
  student: 'Hvor brukes navnet mitt?'
@@ -1130,7 +1130,7 @@ const messages = {
1130
1130
  recentArenaTopics: 'Nye innlegg i arenaen'
1131
1131
  },
1132
1132
  myProfile: {
1133
- title: 'Min Profil',
1133
+ title: 'Min profil',
1134
1134
  disclaimerTitle: {
1135
1135
  employee: 'Kvar blir namnet mitt brukt?',
1136
1136
  student: 'Kvar blir namnet mitt brukt?'
@@ -1130,7 +1130,7 @@ const messages = {
1130
1130
  recentArenaTopics: 'Nye innlegg i arenaen'
1131
1131
  },
1132
1132
  myProfile: {
1133
- title: 'Mov Profijle',
1133
+ title: 'Mov profijle',
1134
1134
  disclaimerTitle: {
1135
1135
  employee: 'Gusnie mov nomme?',
1136
1136
  student: 'Gusnie mov nomme?'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ndla/ui",
3
- "version": "50.5.3",
3
+ "version": "50.6.0",
4
4
  "description": "UI component library for NDLA.",
5
5
  "license": "GPL-3.0",
6
6
  "main": "lib/index.js",
@@ -31,19 +31,19 @@
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",
34
+ "@ndla/accordion": "^3.0.14",
35
+ "@ndla/button": "^12.0.19",
36
+ "@ndla/carousel": "^4.0.20",
37
37
  "@ndla/core": "^4.3.0",
38
38
  "@ndla/dropdown-menu": "^1.0.20",
39
- "@ndla/forms": "^5.2.8",
39
+ "@ndla/forms": "^5.2.9",
40
40
  "@ndla/hooks": "^2.1.4",
41
- "@ndla/icons": "^4.2.5",
41
+ "@ndla/icons": "^4.2.6",
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",
43
+ "@ndla/modal": "^5.0.19",
44
+ "@ndla/notion": "^6.0.20",
45
+ "@ndla/safelink": "^4.1.44",
46
+ "@ndla/select": "^3.2.6",
47
47
  "@ndla/switch": "^1.1.26",
48
48
  "@ndla/tabs": "^3.2.6",
49
49
  "@ndla/tooltip": "^6.0.8",
@@ -71,7 +71,7 @@
71
71
  },
72
72
  "devDependencies": {
73
73
  "@ndla/types-backend": "^0.2.21",
74
- "@ndla/types-embed": "^4.0.10",
74
+ "@ndla/types-embed": "^4.0.11",
75
75
  "css-loader": "^6.7.3",
76
76
  "mini-css-extract-plugin": "^2.7.5",
77
77
  "sass-loader": "^13.2.2",
@@ -81,5 +81,5 @@
81
81
  "publishConfig": {
82
82
  "access": "public"
83
83
  },
84
- "gitHead": "a4093aae160a19db04b67403cd9d6ac1c501f1fb"
84
+ "gitHead": "3930fca2deff61ba578d6c17b8adf89604ccbe7c"
85
85
  }
@@ -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,38 +6,30 @@
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
- .c-icon {
25
- margin-top: 3px;
26
- flex-shrink: 0;
27
- margin-right: ${spacing.small};
28
- height: 18px;
29
- width: 18px;
30
- }
31
24
  `;
32
25
 
33
- const FileListHeading = styled.h3`
34
- ${fonts.sizes('16px', '18px')};
35
- letter-spacing: 0.05em;
26
+ const FileListHeaderWrapper = styled.div`
27
+ display: flex;
28
+ justify-content: space-between;
29
+ align-items: center;
36
30
  margin: 0 0 ${spacing.xsmall} 0;
37
31
  padding-bottom: ${spacing.xsmall};
38
32
  border-bottom: 2px solid ${colors.brand.greyLight};
39
- font-weight: ${fonts.weight.bold};
40
- text-transform: uppercase;
41
33
  `;
42
34
 
43
35
  const FilesList = styled.ul`
@@ -45,11 +37,16 @@ const FilesList = styled.ul`
45
37
  padding: 0;
46
38
  `;
47
39
 
48
- const FileList = ({ children }: Props) => {
40
+ const FileList = ({ children, headingButtons, ...rest }: Props) => {
49
41
  const { t } = useTranslation();
50
42
  return (
51
- <FileListSection>
52
- <FileListHeading>{t('files')}</FileListHeading>
43
+ <FileListSection {...rest}>
44
+ <FileListHeaderWrapper>
45
+ <Heading element="h3" headingStyle="list-title" margin="none">
46
+ {t('files')}
47
+ </Heading>
48
+ <div>{headingButtons}</div>
49
+ </FileListHeaderWrapper>
53
50
  <FilesList>{children}</FilesList>
54
51
  </FileListSection>
55
52
  );
@@ -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;
@@ -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>
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright (c) 2020-present, NDLA.
2
+ * Copyright (c) 2019-present, NDLA.
3
3
  *
4
4
  * This source code is licensed under the GPLv3 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -12,15 +12,16 @@ import { css } from '@emotion/react';
12
12
  import styled from '@emotion/styled';
13
13
  import { ButtonV2 } from '@ndla/button';
14
14
  import { breakpoints, colors, misc, mq, spacing } from '@ndla/core';
15
- import { HumanMaleBoard } from '@ndla/icons/common';
15
+ import { Additional, HumanMaleBoard } from '@ndla/icons/common';
16
16
  import { SafeLinkButton } from '@ndla/safelink';
17
17
  import { Switch } from '@ndla/switch';
18
18
  import { Heading } from '@ndla/typography';
19
19
  import { uuid } from '@ndla/util';
20
20
 
21
21
  const StyledWrapper = styled.nav`
22
- margin: 20px 0 34px;
22
+ margin: ${spacing.normal} 0 ${spacing.mediumlarge};
23
23
  `;
24
+
24
25
  const StyledHeadingWrapper = styled.div`
25
26
  display: flex;
26
27
  justify-content: space-between;
@@ -33,77 +34,37 @@ const StyledHeading = styled(Heading)`
33
34
  }
34
35
  `;
35
36
 
36
- type listProps = {
37
- direction?: 'horizontal' | 'vertical' | 'floating';
38
- };
39
- const StyledList = styled.ul<listProps>`
37
+ const StyledList = styled.ul`
40
38
  list-style: none;
41
39
  margin: 0;
42
40
  padding: 0;
43
- ${(props) =>
44
- props.direction !== 'floating' &&
45
- css`
46
- ${mq.range({ from: breakpoints.tablet })} {
47
- column-count: 2;
48
- column-gap: 20px;
49
- ${props.direction === 'horizontal' &&
50
- css`
51
- display: grid;
52
- grid-template-columns: repeat(2, 1fr);
53
- `}
54
- }
55
- ${mq.range({ from: breakpoints.tabletWide })} {
56
- column-count: 3;
57
- column-gap: 20px;
58
- ${props.direction === 'horizontal' &&
59
- css`
60
- grid-template-columns: repeat(3, 1fr);
61
- `}
62
- }
63
- `};
41
+
42
+ &[data-direction='horizontal'] {
43
+ ${mq.range({ from: breakpoints.tablet })} {
44
+ column-count: 2;
45
+ column-gap: 20px;
46
+ display: grid;
47
+ grid-template-columns: repeat(2, 1fr);
48
+ }
49
+ ${mq.range({ from: breakpoints.tabletWide })} {
50
+ column-count: 3;
51
+ column-gap: 20px;
52
+ grid-template-columns: repeat(3, 1fr);
53
+ }
54
+ }
64
55
  `;
65
- type additionalResourceProps = {
66
- isAdditionalResource?: boolean;
67
- isRestrictedResource?: boolean;
68
- lighter?: boolean;
69
- selected?: boolean;
70
- listDirection?: listProps['direction'];
71
- };
72
56
 
73
- const StyledListItem = styled.li<additionalResourceProps>`
57
+ const StyledListItem = styled.li`
74
58
  margin-bottom: 0;
75
59
  break-inside: avoid;
76
- ${(props) =>
77
- props.listDirection === 'floating' &&
78
- css`
79
- display: inline-block;
80
- margin: 0 ${spacing.xsmall} ${spacing.xsmall} 0;
81
- ${mq.range({ until: breakpoints.mobileWide })} {
82
- display: block;
83
- }
84
- `}
85
- `;
86
60
 
87
- const StyledListElementWrapper = styled.div<additionalResourceProps>`
88
- position: relative;
89
- ${(props) =>
90
- props.isAdditionalResource &&
91
- css`
92
- & > * {
93
- border: 1px dashed ${props.lighter && !props.selected ? `${colors.brand.tertiary}` : `${colors.brand.dark}`};
94
- background-clip: padding-box;
95
- :hover,
96
- :focus {
97
- border: 1px dashed ${colors.brand.dark};
98
- background-clip: padding-box;
99
- color: ${colors.white};
100
- ${StyledAdditionalResourceMark} {
101
- color: ${colors.white};
102
- border-color: ${colors.white};
103
- }
104
- }
105
- }
106
- `}
61
+ &[data-direction='floating'] {
62
+ display: inline-block;
63
+ margin: 0 ${spacing.xsmall} ${spacing.xsmall} 0;
64
+ ${mq.range({ until: breakpoints.mobileWide })} {
65
+ display: block;
66
+ }
67
+ }
107
68
  `;
108
69
 
109
70
  const StyledSpacingElement = styled.span`
@@ -122,21 +83,22 @@ const StyledButtonContent = styled.span`
122
83
  align-items: center;
123
84
  `;
124
85
 
125
- const StyledButtonContentText = styled.span<additionalResourceProps>`
126
- ${(props) => {
127
- if (props.isAdditionalResource && props.isRestrictedResource) {
128
- return `padding-left: ${spacing.medium};`;
129
- }
130
- if (props.isAdditionalResource || props.isRestrictedResource) {
131
- return `padding-left: ${spacing.small};`;
132
- }
133
- }}
86
+ const StyledButtonContentText = styled.span`
87
+ &[data-additional='true'][data-restricted='true'] {
88
+ padding-left: ${spacing.medium};
89
+ }
90
+ &[data-additional='true'] {
91
+ padding-left: ${spacing.small};
92
+ }
93
+ &[data-restricted='true'] {
94
+ padding-left: ${spacing.small};
95
+ }
134
96
  `;
135
97
 
136
98
  const StyledMarksWrapper = styled.span`
137
99
  position: absolute;
138
- left: 7px;
139
- top: 6px;
100
+ left: ${spacing.xxsmall};
101
+ top: ${spacing.xsmall};
140
102
  display: flex;
141
103
  align-items: center;
142
104
  & > * {
@@ -146,32 +108,45 @@ const StyledMarksWrapper = styled.span`
146
108
  margin-left: 0;
147
109
  }
148
110
  `;
149
- const StyledAdditionalResourceMark = styled.span<additionalResourceProps>`
150
- color: ${(props) => (props.lighter && !props.selected ? `${colors.brand.dark}` : `${colors.white}`)};
151
- font-weight: 600;
152
- font-size: 12px;
153
- line-height: 18px;
154
- text-align: center;
155
- display: inline-block;
156
- width: 20px;
157
- height: 20px;
158
- border: 1px solid ${(props) => (props.lighter && !props.selected ? `${colors.brand.dark}` : `${colors.white}`)};
159
- border-radius: 100px;
160
- transition: ${misc.transition.default};
111
+
112
+ const StyledAdditional = styled(Additional)`
113
+ fill: ${colors.white};
114
+ width: ${spacing.nsmall};
115
+ height: ${spacing.nsmall};
161
116
  `;
162
117
 
163
118
  const StyledHumanBoardIconWrapper = styled.span`
164
119
  display: flex;
165
120
  `;
121
+
166
122
  const StyledButtonContentSelected = styled.span`
167
123
  width: 10px;
168
124
  height: 10px;
169
- border-radius: 50%;
125
+ border-radius: ${misc.borderRadiusLarge};
170
126
  background: ${colors.white};
171
127
  flex-shrink: 0;
172
128
  margin-left: ${spacing.small};
173
129
  `;
174
130
 
131
+ const StyledListElementWrapper = styled.div`
132
+ position: relative;
133
+ &[data-additional='true'] {
134
+ & > * {
135
+ border: 1px dashed ${colors.brand.dark};
136
+ background-clip: padding-box;
137
+ :hover,
138
+ :focus {
139
+ border: 1px dashed ${colors.brand.dark};
140
+ background-clip: padding-box;
141
+ color: ${colors.white};
142
+ }
143
+ &[data-color-mode='light'][data-selected='false'] {
144
+ border: 1px dashed ${colors.brand.tertiary};
145
+ }
146
+ }
147
+ }
148
+ `;
149
+
175
150
  const listElementStyle = css`
176
151
  display: flex;
177
152
  flex: 1;
@@ -186,6 +161,7 @@ export type ItemProps = {
186
161
  isAdditionalResource?: boolean;
187
162
  isRestrictedResource?: boolean;
188
163
  };
164
+
189
165
  type Props = {
190
166
  heading?: string;
191
167
  colorMode?: 'primary' | 'darker' | 'light' | 'greyLightest' | 'greyLighter';
@@ -194,7 +170,7 @@ type Props = {
194
170
  onClick?: (event: MouseEvent<HTMLElement>, id?: string) => void;
195
171
  hasAdditionalResources?: boolean;
196
172
  showAdditionalResources?: boolean;
197
- listDirection?: listProps['direction'];
173
+ listDirection?: 'horizontal' | 'floating';
198
174
  invertedStyle?: boolean;
199
175
  onToggleAdditionalResources?: (checked: boolean) => void;
200
176
  };
@@ -231,13 +207,13 @@ export const NavigationBox = ({
231
207
  />
232
208
  )}
233
209
  </StyledHeadingWrapper>
234
- <StyledList data-testid="nav-box-list" direction={listDirection}>
210
+ <StyledList data-testid="nav-box-list" data-direction={listDirection}>
235
211
  {items?.map((item: ItemProps) => (
236
- <StyledListItem key={item.label} listDirection={listDirection} data-testid="nav-box-item">
212
+ <StyledListItem key={item.label} data-direction={listDirection} data-testid="nav-box-item">
237
213
  <StyledListElementWrapper
238
- isAdditionalResource={item.isAdditionalResource}
239
- lighter={colorMode === 'light'}
240
- selected={item.selected}
214
+ data-additional={item.isAdditionalResource}
215
+ data-color-mode={colorMode}
216
+ data-selected={item.selected}
241
217
  >
242
218
  <ListElementType
243
219
  to={item.url ?? ''}
@@ -253,16 +229,12 @@ export const NavigationBox = ({
253
229
  >
254
230
  <StyledButtonContent>
255
231
  <StyledButtonContentText
256
- isAdditionalResource={item.isAdditionalResource}
257
- isRestrictedResource={item.isRestrictedResource}
258
- lighter={colorMode === 'light'}
232
+ data-additional={item.isAdditionalResource}
233
+ data-restricted={item.isRestrictedResource}
234
+ data-color-mode={colorMode}
259
235
  >
260
236
  <StyledMarksWrapper>
261
- {item.isAdditionalResource && (
262
- <StyledAdditionalResourceMark lighter={colorMode === 'light'} selected={item.selected}>
263
- T
264
- </StyledAdditionalResourceMark>
265
- )}
237
+ {item.isAdditionalResource && <StyledAdditional aria-label={t('resource.additionalTooltip')} />}
266
238
  {item.isRestrictedResource && (
267
239
  <StyledHumanBoardIconWrapper>
268
240
  <HumanMaleBoard />
@@ -264,12 +264,12 @@ const ResourceItem = ({
264
264
  <>
265
265
  {additional && (
266
266
  <IconWrapper id={additionalId} aria-label={contentTypeDescription} title={contentTypeDescription}>
267
- <Additional />
267
+ <Additional color={colors.brand.dark} />
268
268
  </IconWrapper>
269
269
  )}
270
270
  {!additional && (
271
271
  <IconWrapper id={coreId} aria-label={contentTypeDescription} title={contentTypeDescription}>
272
- <Core />
272
+ <Core color={colors.brand.primary} />
273
273
  </IconWrapper>
274
274
  )}
275
275
  </>