@ndla/ui 27.1.1 → 27.1.3

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 (53) hide show
  1. package/es/MyNdla/Resource/FolderInput.js +65 -77
  2. package/es/Resource/resourceComponents.js +13 -13
  3. package/es/TreeStructure/AddFolderButton.js +87 -0
  4. package/es/TreeStructure/ComboboxButton.js +14 -65
  5. package/es/TreeStructure/FolderItem.js +12 -15
  6. package/es/TreeStructure/FolderItems.js +12 -14
  7. package/es/TreeStructure/TreeStructure.js +74 -55
  8. package/es/locale/messages-en.js +1 -1
  9. package/es/locale/messages-nb.js +1 -1
  10. package/es/locale/messages-nn.js +1 -1
  11. package/es/locale/messages-se.js +1 -1
  12. package/es/locale/messages-sma.js +1 -1
  13. package/lib/MyNdla/Resource/FolderInput.d.ts +7 -6
  14. package/lib/MyNdla/Resource/FolderInput.js +65 -73
  15. package/lib/Resource/resourceComponents.js +13 -13
  16. package/lib/TreeStructure/AddFolderButton.d.ts +16 -0
  17. package/lib/TreeStructure/AddFolderButton.js +100 -0
  18. package/lib/TreeStructure/ComboboxButton.d.ts +2 -6
  19. package/lib/TreeStructure/ComboboxButton.js +20 -65
  20. package/lib/TreeStructure/FolderItem.d.ts +1 -1
  21. package/lib/TreeStructure/FolderItem.js +12 -15
  22. package/lib/TreeStructure/FolderItems.d.ts +4 -3
  23. package/lib/TreeStructure/FolderItems.js +12 -15
  24. package/lib/TreeStructure/TreeStructure.d.ts +4 -4
  25. package/lib/TreeStructure/TreeStructure.js +74 -55
  26. package/lib/TreeStructure/index.d.ts +1 -1
  27. package/lib/TreeStructure/types.d.ts +8 -7
  28. package/lib/index.d.ts +1 -1
  29. package/lib/locale/messages-en.js +1 -1
  30. package/lib/locale/messages-nb.js +1 -1
  31. package/lib/locale/messages-nn.js +1 -1
  32. package/lib/locale/messages-se.js +1 -1
  33. package/lib/locale/messages-sma.js +1 -1
  34. package/package.json +7 -7
  35. package/src/MyNdla/Resource/FolderInput.tsx +69 -73
  36. package/src/Resource/resourceComponents.tsx +4 -6
  37. package/src/TreeStructure/AddFolderButton.tsx +79 -0
  38. package/src/TreeStructure/ComboboxButton.tsx +11 -56
  39. package/src/TreeStructure/FolderItem.tsx +5 -6
  40. package/src/TreeStructure/FolderItems.tsx +8 -15
  41. package/src/TreeStructure/TreeStructure.tsx +60 -45
  42. package/src/TreeStructure/index.ts +1 -1
  43. package/src/TreeStructure/types.ts +13 -7
  44. package/src/index.ts +1 -1
  45. package/src/locale/messages-en.ts +1 -1
  46. package/src/locale/messages-nb.ts +1 -1
  47. package/src/locale/messages-nn.ts +1 -1
  48. package/src/locale/messages-se.ts +1 -1
  49. package/src/locale/messages-sma.ts +1 -1
  50. package/es/TreeStructure/FolderNameInput.js +0 -143
  51. package/lib/TreeStructure/FolderNameInput.d.ts +0 -19
  52. package/lib/TreeStructure/FolderNameInput.js +0 -159
  53. package/src/TreeStructure/FolderNameInput.tsx +0 -167
@@ -993,7 +993,7 @@ var messages = _objectSpread(_objectSpread({
993
993
  myPage: 'Mi side',
994
994
  deleteAccount: 'Slett Min NDLA',
995
995
  logout: 'Logg ut av Min NDLA',
996
- loginText: 'Loggmed Feide for å tilgang til Min NDLA. Vi ber om at du ikkje skriv noko støtande, personsensitiv informasjon eller andre persondata i tekstfelt. Les vår ',
996
+ loginText: 'For å kunne bruke tjenesten Min NDLA må du vere elev eller jobbe ein skule i eit fylke som er med i NDLA-samarbeidet. Vi ber om at du ikkje skriv noko støtande, personsensitiv informasjon eller andre persondata i tekstfelt. Les vår ',
997
997
  loginTextLink: 'personvernerklæring her',
998
998
  loginTerms: 'Logg på med Feide for å få tilgang. Ved å logge på godkjennar du våre vilkår for bruk',
999
999
  loginResourcePitch: 'Ønsker du å favorittmerke denne sida?',
@@ -993,7 +993,7 @@ var messages = _objectSpread(_objectSpread({
993
993
  myPage: 'Mu siidu',
994
994
  deleteAccount: 'Sihko mu NDLA',
995
995
  logout: 'Logge eret mu NDLAs',
996
- loginText: 'Loggmed Feide for å tilgang til Min NDLA. Vi ber om at du ikkje skriver noko støtende, personsensitiv informasjon eller andre persondata i tekstfelt. Les vår ',
996
+ loginText: 'For å kunne bruke tjenesten Min NDLA må du vere elev eller jobbe ein skule i eit fylke som er med i NDLA-samarbeidet. Vi ber om at du ikkje skriv noko støtande, personsensitiv informasjon eller andre persondata i tekstfelt. Les vår ',
997
997
  loginTextLink: 'personvernerklæring her',
998
998
  loginTerms: 'Logge Feide bokte vai oaččut beassanlobi. Go logget sisa de dohkkehat min geavahaneavttuid.',
999
999
  loginResourcePitch: 'Dáhtut go merket siiddu oiddohin?',
@@ -993,7 +993,7 @@ var messages = _objectSpread(_objectSpread({
993
993
  myPage: 'Min side',
994
994
  deleteAccount: 'Slett Min NDLA',
995
995
  logout: 'Logg ut av Min NDLA',
996
- loginText: 'Loggmed Feide for å tilgang til Min NDLA. Vi ber om at du ikkje skriver noko støtende, personsensitiv informasjon eller andre persondata i tekstfelt. Les vår ',
996
+ loginText: 'For å kunne bruke tjenesten Min NDLA må du vere elev eller jobbe ein skule i eit fylke som er med i NDLA-samarbeidet. Vi ber om at du ikkje skriv noko støtande, personsensitiv informasjon eller andre persondata i tekstfelt. Les vår ',
997
997
  loginTextLink: 'personvernerklæring her',
998
998
  loginTerms: 'Logg på med Feide for å få tilgang. Ved å logge på godkjenner du våre vilkår for bruk',
999
999
  loginResourcePitch: 'Ønsker du å favorittmerke denne siden?',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ndla/ui",
3
- "version": "27.1.1",
3
+ "version": "27.1.3",
4
4
  "description": "UI component library for NDLA.",
5
5
  "license": "GPL-3.0",
6
6
  "main": "lib/index.js",
@@ -32,16 +32,16 @@
32
32
  ],
33
33
  "dependencies": {
34
34
  "@ndla/article-scripts": "^3.0.2",
35
- "@ndla/button": "^3.5.2",
35
+ "@ndla/button": "^3.6.0",
36
36
  "@ndla/carousel": "^1.2.23",
37
37
  "@ndla/core": "^2.3.5",
38
- "@ndla/forms": "^3.3.2",
38
+ "@ndla/forms": "^3.3.4",
39
39
  "@ndla/hooks": "^1.1.6",
40
40
  "@ndla/icons": "^1.13.0",
41
41
  "@ndla/licenses": "^5.0.17",
42
- "@ndla/modal": "^1.4.0",
43
- "@ndla/notion": "^3.1.43",
44
- "@ndla/safelink": "^2.2.16",
42
+ "@ndla/modal": "^1.5.0",
43
+ "@ndla/notion": "^3.1.45",
44
+ "@ndla/safelink": "^2.2.18",
45
45
  "@ndla/switch": "^0.1.13",
46
46
  "@ndla/tabs": "^1.1.22",
47
47
  "@ndla/tooltip": "^2.2.1",
@@ -85,5 +85,5 @@
85
85
  "publishConfig": {
86
86
  "access": "public"
87
87
  },
88
- "gitHead": "2247cc7ddac3d0f9b76f1563c41af22db0c283e9"
88
+ "gitHead": "88e2b2d4c85688382f9edb3e1d9a31d45fae00ab"
89
89
  }
@@ -7,110 +7,106 @@
7
7
  */
8
8
 
9
9
  import styled from '@emotion/styled';
10
- import { IconButton } from '@ndla/button';
11
- import { FolderOutlined } from '@ndla/icons/contentType';
10
+ import { IconButton, IconButtonV2 } from '@ndla/button';
12
11
  import { Cross } from '@ndla/icons/action';
13
- import React, { ChangeEvent, KeyboardEvent, useRef, useState } from 'react';
12
+ import React, { ComponentProps, forwardRef, useEffect } from 'react';
13
+ import { isMobile } from 'react-device-detect';
14
14
  import { useTranslation } from 'react-i18next';
15
15
  import { colors, spacing } from '@ndla/core';
16
- import { Input } from '@ndla/forms';
17
- import { css } from '@emotion/core';
16
+ import { InputV2 } from '@ndla/forms';
18
17
  import { Done } from '@ndla/icons/editor';
18
+ import { Spinner } from '@ndla/icons';
19
+ import { useForwardedRef } from '@ndla/util';
20
+
21
+ interface Props extends ComponentProps<typeof InputV2> {
22
+ loading?: boolean;
23
+ onClose?: () => void;
24
+ onSave: () => void;
25
+ }
19
26
 
20
27
  // Source: https://kovart.github.io/dashed-border-generator/
21
- const borderStyle = `url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' stroke='${encodeURIComponent(
22
- colors.brand.tertiary,
23
- )}' stroke-width='2' stroke-dasharray='8%2c8' stroke-dashoffset='4' stroke-linecap='square'/%3e%3c/svg%3e")`;
28
+ const borderStyle = (error?: boolean) =>
29
+ `url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' stroke='${encodeURIComponent(
30
+ error ? colors.support.red : colors.brand.tertiary,
31
+ )}' stroke-width='2' stroke-dasharray='8%2c8' stroke-dashoffset='4' stroke-linecap='square'/%3e%3c/svg%3e")`;
24
32
 
25
- const StyledFolderIcon = styled.span`
26
- display: flex;
27
- padding: ${spacing.small};
28
- svg {
29
- color: ${colors.brand.primary};
30
- height: 20px;
31
- width: 20px;
32
- }
33
- `;
33
+ interface StyledInputProps {
34
+ error?: string;
35
+ }
34
36
 
35
- const inputWrapperStyle = css`
36
- padding: ${spacing.small};
37
- background: none;
38
- background-image: ${borderStyle};
37
+ const StyledInput = styled(InputV2)<StyledInputProps>`
38
+ background-color: white;
39
+ background-image: ${({ error }) => borderStyle(!!error)};
39
40
  border: none;
40
- `;
41
-
42
- const StyledInput = styled(Input)`
43
- && {
44
- flex-grow: 1;
45
- flex-basis: 0;
46
- min-width: 0;
41
+ border-radius: 0;
42
+ flex-wrap: nowrap;
43
+ input {
47
44
  line-height: 1.75em;
48
45
  color: ${colors.brand.primary};
46
+ caret-color: ${colors.brand.tertiary};
49
47
  ::selection {
50
48
  background: ${colors.brand.lighter};
51
49
  }
50
+ ::placeholder {
51
+ color: ${colors.brand.tertiary};
52
+ }
52
53
  }
53
54
  `;
54
55
 
55
56
  const Row = styled.div`
56
57
  display: flex;
57
- gap: ${spacing.xsmall};
58
- padding-right: ${spacing.small};
58
+ align-items: center;
59
+ gap: ${spacing.xxsmall};
60
+ padding-right: ${spacing.xsmall};
59
61
  `;
60
62
 
61
- interface Props {
62
- onAddFolder: (name: string) => void;
63
- onClose: () => void;
64
- autoSelect?: boolean;
65
- }
66
-
67
- const FolderInput = ({ onAddFolder, onClose, autoSelect }: Props) => {
63
+ const FolderInput = forwardRef<HTMLInputElement, Props>(({ loading, error, onClose, onSave, ...rest }, ref) => {
68
64
  const { t } = useTranslation();
69
- const newFolderText = t('treeStructure.newFolder.defaultName');
70
- const [input, setInput] = useState<string>(newFolderText);
71
- const inputRef = useRef<HTMLInputElement>(null);
72
-
73
- const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {
74
- setInput(e.target.value);
75
- };
65
+ const inputRef = useForwardedRef(ref);
76
66
 
77
- const onKeydown = (e: KeyboardEvent<HTMLInputElement>) => {
78
- if (e.key === 'Enter' && input.trim()) {
79
- e.preventDefault();
80
- onAddFolder(input);
81
- } else if (e.key === 'Escape') {
82
- e.preventDefault();
83
- onClose();
67
+ useEffect(() => {
68
+ if (isMobile) {
69
+ inputRef.current?.scrollIntoView({ behavior: 'smooth' });
84
70
  }
85
- };
71
+ // eslint-disable-next-line react-hooks/exhaustive-deps
72
+ }, []);
86
73
 
87
74
  return (
88
75
  <StyledInput
89
- autoSelect={autoSelect}
90
- customCss={inputWrapperStyle}
91
- warningText={!input.trim() ? t('myNdla.folder.missingName') : undefined}
92
- ref={inputRef}
93
- value={input}
94
- onChange={handleInputChange}
95
- onKeyDown={onKeydown}
96
- aria-label={newFolderText}
97
- iconLeft={
98
- <StyledFolderIcon>
99
- <FolderOutlined />
100
- </StyledFolderIcon>
101
- }
102
- iconRight={
76
+ white
77
+ error={error}
78
+ aria-disabled={loading ? true : undefined}
79
+ aria-describedby={'folder-input-spinner'}
80
+ ref={ref}
81
+ after={
103
82
  <Row>
104
- <IconButton aria-label={t('close')} size="small" ghostPill onClick={onClose}>
105
- <Cross />
106
- </IconButton>
107
- <IconButton aria-label={t('save')} size="small" ghostPill onClick={() => onAddFolder(input)}>
108
- <Done />
109
- </IconButton>
83
+ {!loading && (
84
+ <>
85
+ {!error && (
86
+ <IconButtonV2
87
+ variant={'ghost'}
88
+ colorTheme="light"
89
+ tabIndex={0}
90
+ aria-label={t('save')}
91
+ title={t('save')}
92
+ size="small"
93
+ onClick={onSave}>
94
+ <Done />
95
+ </IconButtonV2>
96
+ )}
97
+ <IconButton aria-label={t('close')} title={t('close')} size="small" ghostPill onClick={onClose}>
98
+ <Cross />
99
+ </IconButton>
100
+ </>
101
+ )}
102
+ <div aria-live="assertive">
103
+ {loading && <Spinner size="normal" margin={spacing.small} id="folder-spinner" aria-label={t('loading')} />}
104
+ </div>
110
105
  </Row>
111
106
  }
107
+ {...rest}
112
108
  />
113
109
  );
114
- };
110
+ });
115
111
 
116
112
  export default FolderInput;
@@ -185,12 +185,10 @@ export const TopicList = ({ topics }: TopicListProps) => {
185
185
  return (
186
186
  <StyledTopicList aria-label={t('navigation.topics')}>
187
187
  {topics.map((topic, i) => (
188
- <>
189
- <StyledTopicListElement key={topic}>
190
- {topic}
191
- {i !== topics.length - 1 && <StyledTopicDivider aria-hidden="true">•</StyledTopicDivider>}
192
- </StyledTopicListElement>
193
- </>
188
+ <StyledTopicListElement key={topic}>
189
+ {topic}
190
+ {i !== topics.length - 1 && <StyledTopicDivider aria-hidden="true">•</StyledTopicDivider>}
191
+ </StyledTopicListElement>
194
192
  ))}
195
193
  </StyledTopicList>
196
194
  );
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Copyright (c) 2022-present, NDLA.
3
+ *
4
+ * This source code is licensed under the GPLv3 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import React, { useRef } from 'react';
10
+ import { useTranslation } from 'react-i18next';
11
+ import Tooltip from '@ndla/tooltip';
12
+ import styled from '@emotion/styled';
13
+ import { ButtonV2 as Button } from '@ndla/button';
14
+ import { Plus } from '@ndla/icons/action';
15
+ import { FolderType } from './types';
16
+
17
+ interface AddFolderButtonProps {
18
+ canAddFolder: boolean;
19
+ focusedFolder?: FolderType;
20
+ setNewFolderParentId: (id?: string) => void;
21
+ }
22
+
23
+ const StyledAddFolderButton = styled(Button)`
24
+ &,
25
+ &:disabled {
26
+ border-color: transparent;
27
+ }
28
+ `;
29
+
30
+ const StyledPlus = styled(Plus)`
31
+ height: 24px;
32
+ width: 24px;
33
+ `;
34
+
35
+ const AddFolderButton = ({ canAddFolder, setNewFolderParentId, focusedFolder }: AddFolderButtonProps) => {
36
+ const { t } = useTranslation();
37
+ const ref = useRef<HTMLButtonElement>(null);
38
+ return (
39
+ <Tooltip
40
+ tooltip={
41
+ canAddFolder
42
+ ? t('myNdla.newFolderUnder', {
43
+ folderName: focusedFolder?.name,
44
+ })
45
+ : t('treeStructure.maxFoldersAlreadyAdded')
46
+ }>
47
+ <StyledAddFolderButton
48
+ ref={ref}
49
+ variant="outline"
50
+ shape="pill"
51
+ disabled={!canAddFolder}
52
+ aria-label={
53
+ canAddFolder
54
+ ? t('myNdla.newFolderUnder', {
55
+ folderName: focusedFolder?.name,
56
+ })
57
+ : t('treeStructure.maxFoldersAlreadyAdded')
58
+ }
59
+ onMouseDown={(e) => {
60
+ e.preventDefault();
61
+ e.stopPropagation();
62
+ ref.current?.focus();
63
+ }}
64
+ onMouseUp={(e) => {
65
+ e.preventDefault();
66
+ e.stopPropagation();
67
+ ref.current?.focus();
68
+ }}
69
+ onClick={(e) => {
70
+ e.currentTarget.focus();
71
+ setNewFolderParentId(focusedFolder?.id);
72
+ }}>
73
+ <StyledPlus /> {t('myNdla.newFolder')}
74
+ </StyledAddFolderButton>
75
+ </Tooltip>
76
+ );
77
+ };
78
+
79
+ export default AddFolderButton;
@@ -7,13 +7,9 @@
7
7
  */
8
8
 
9
9
  import React, { KeyboardEvent } from 'react';
10
- import { useTranslation } from 'react-i18next';
11
10
  import styled from '@emotion/styled';
12
11
  import { useForwardedRef } from '@ndla/util';
13
- import Tooltip from '@ndla/tooltip';
14
- import { colors, spacing } from '@ndla/core';
15
- import { IFolder } from '@ndla/types-learningpath-api';
16
- import { Plus } from '@ndla/icons/action';
12
+ import { breakpoints, colors, mq, spacing } from '@ndla/core';
17
13
  import { ChevronUp, ChevronDown } from '@ndla/icons/common';
18
14
  import { forwardRef } from 'react';
19
15
  import { ButtonV2 as Button, IconButtonV2 as IconButton } from '@ndla/button';
@@ -27,8 +23,8 @@ interface StyledRowProps {
27
23
 
28
24
  const StyledRow = styled.div<StyledRowProps>`
29
25
  display: flex;
30
- justify-content: space-between;
31
26
  padding: ${spacing.xxsmall};
27
+ align-items: center;
32
28
  border-bottom: ${({ isOpen }) => isOpen && `1px solid ${colors.brand.tertiary}`};
33
29
  `;
34
30
  const StyledSelectedFolder = styled(Button)`
@@ -44,35 +40,25 @@ const StyledSelectedFolder = styled(Button)`
44
40
  :focus-visible {
45
41
  outline: none;
46
42
  }
47
- `;
48
-
49
- const StyledAddFolderButton = styled(Button)`
50
- &,
51
- &:disabled {
52
- border-color: transparent;
43
+ ${mq.range({ until: breakpoints.tablet })} {
44
+ min-height: 4rem;
45
+ max-height: 4rem;
46
+ text-align: start;
53
47
  }
54
48
  `;
55
49
 
56
- const StyledPlus = styled(Plus)`
57
- height: 24px;
58
- width: 24px;
59
- `;
60
-
61
50
  interface Props {
62
51
  showTree: boolean;
63
52
  type: TreeStructureType;
64
53
  label?: string;
65
54
  focusedFolder?: FolderType;
66
55
  selectedFolder?: FolderType;
67
- setSelectedFolder: (folder?: FolderType) => void;
56
+ setSelectedFolder: (folder: FolderType) => void;
68
57
  onToggleTree: (open: boolean) => void;
69
58
  flattenedFolders: FolderType[];
70
59
  onOpenFolder: (id: string) => void;
71
60
  onCloseFolder: (id: string) => void;
72
- setFocusedFolder: (folder?: FolderType) => void;
73
- onNewFolder?: (name: string, parentId: string) => Promise<IFolder>;
74
- maxLevel: number;
75
- setNewFolderParentId: (id?: string) => void;
61
+ setFocusedFolder: (folder: FolderType) => void;
76
62
  }
77
63
 
78
64
  const ComboboxButton = forwardRef<HTMLButtonElement, Props>(
@@ -89,18 +75,14 @@ const ComboboxButton = forwardRef<HTMLButtonElement, Props>(
89
75
  setFocusedFolder,
90
76
  onOpenFolder,
91
77
  onCloseFolder,
92
- onNewFolder,
93
- maxLevel,
94
- setNewFolderParentId,
95
78
  },
96
79
  ref,
97
80
  ) => {
98
- const { t } = useTranslation();
99
81
  const innerRef = useForwardedRef(ref);
100
82
 
101
83
  const onKeyDown = (e: KeyboardEvent<HTMLButtonElement>) => {
102
84
  if (e.key === 'Enter') {
103
- if (showTree) {
85
+ if (showTree && focusedFolder) {
104
86
  setSelectedFolder(focusedFolder);
105
87
  }
106
88
  return;
@@ -118,7 +100,6 @@ const ComboboxButton = forwardRef<HTMLButtonElement, Props>(
118
100
  }
119
101
  };
120
102
 
121
- const canAddFolder = selectedFolder && selectedFolder?.breadcrumbs.length < (maxLevel || 1);
122
103
  return (
123
104
  <StyledRow isOpen={showTree}>
124
105
  <StyledSelectedFolder
@@ -137,35 +118,11 @@ const ComboboxButton = forwardRef<HTMLButtonElement, Props>(
137
118
  shape="sharp"
138
119
  onKeyDown={onKeyDown}
139
120
  onClick={() => {
121
+ innerRef.current?.focus();
140
122
  onToggleTree(!showTree);
141
123
  }}>
142
124
  {selectedFolder?.name}
143
125
  </StyledSelectedFolder>
144
- {onNewFolder && showTree && (
145
- <Tooltip
146
- tooltip={
147
- canAddFolder
148
- ? t('myNdla.newFolderUnder', {
149
- folderName: selectedFolder?.name,
150
- })
151
- : t('treeStructure.maxFoldersAlreadyAdded')
152
- }>
153
- <StyledAddFolderButton
154
- variant="outline"
155
- shape="pill"
156
- disabled={!canAddFolder}
157
- aria-label={
158
- canAddFolder
159
- ? t('myNdla.newFolderUnder', {
160
- folderName: selectedFolder?.name,
161
- })
162
- : t('treeStructure.maxFoldersAlreadyAdded')
163
- }
164
- onClick={() => setNewFolderParentId(focusedFolder?.id)}>
165
- <StyledPlus /> {t('myNdla.newFolder')}
166
- </StyledAddFolderButton>
167
- </Tooltip>
168
- )}
169
126
  <IconButton
170
127
  aria-hidden
171
128
  aria-label=""
@@ -174,9 +131,7 @@ const ComboboxButton = forwardRef<HTMLButtonElement, Props>(
174
131
  colorTheme="greyLighter"
175
132
  size="small"
176
133
  onClick={() => {
177
- if (!showTree) {
178
- innerRef.current?.focus();
179
- }
134
+ innerRef.current?.focus();
180
135
  onToggleTree(!showTree);
181
136
  }}>
182
137
  {showTree ? <ChevronUp /> : <ChevronDown />}
@@ -37,6 +37,9 @@ const OpenButton = styled.span<{ isOpen: boolean }>`
37
37
  `;
38
38
 
39
39
  const StyledName = styled.span`
40
+ white-space: nowrap;
41
+ overflow: hidden;
42
+ text-overflow: ellipsis;
40
43
  grid-column-start: 2;
41
44
  text-align: left;
42
45
  `;
@@ -63,7 +66,6 @@ const FolderName = styled(Button, { shouldForwardProp })<FolderNameProps>`
63
66
  color: ${({ isCreatingFolder, focused }) =>
64
67
  isCreatingFolder && focused ? colors.brand.primary : colors.text.primary};
65
68
  transition: ${animations.durations.superFast};
66
- line-height: 1;
67
69
  word-break: break-word;
68
70
 
69
71
  &:hover {
@@ -93,7 +95,6 @@ const FolderNameLink = styled(SafeLink, { shouldForwardProp })<FolderNameProps>`
93
95
  font-weight: ${({ selected }) => selected && fonts.weight.semibold};
94
96
  font-size: ${fonts.sizes('16px')};
95
97
  transition: ${animations.durations.superFast};
96
- line-height: 1;
97
98
  word-break: break-word;
98
99
  &:hover,
99
100
  &:focus {
@@ -116,7 +117,6 @@ const FolderItem = ({
116
117
  selectedFolder,
117
118
  onCloseFolder,
118
119
  onOpenFolder,
119
- onSelectFolder,
120
120
  setFocusedFolder,
121
121
  setSelectedFolder,
122
122
  targetResource,
@@ -142,7 +142,6 @@ const FolderItem = ({
142
142
  if (selected) {
143
143
  closeTree();
144
144
  }
145
- onSelectFolder?.(id);
146
145
  }
147
146
  };
148
147
 
@@ -230,7 +229,7 @@ const FolderItem = ({
230
229
  selected={selected}
231
230
  disabled={loading}
232
231
  onFocus={(e) => {
233
- setFocusedFolder(focusedFolder || folder, true);
232
+ setFocusedFolder(focusedFolder || folder);
234
233
  }}
235
234
  onClick={handleClickFolder}
236
235
  isCreatingFolder={isCreatingFolder}>
@@ -241,7 +240,7 @@ const FolderItem = ({
241
240
  isOpen={isOpen}
242
241
  onClick={(e) => {
243
242
  e.stopPropagation();
244
- setFocusedFolder(folder, true);
243
+ setFocusedFolder(folder);
245
244
  if (isOpen) {
246
245
  onCloseFolder(id);
247
246
  } else {
@@ -10,8 +10,7 @@ import React, { ReactNode } from 'react';
10
10
  import styled from '@emotion/styled';
11
11
  import { animations } from '@ndla/core';
12
12
  import FolderItem from './FolderItem';
13
- import FolderNameInput from './FolderNameInput';
14
- import { CommonFolderItemsProps, FolderType, TreeStructureType } from './types';
13
+ import { CommonFolderItemsProps, FolderType, NewFolderInputFunc, OnCreatedFunc, TreeStructureType } from './types';
15
14
  import NavigationLink from './NavigationLink';
16
15
  import { treestructureId } from './helperFunctions';
17
16
 
@@ -42,10 +41,11 @@ export interface FolderItemsProps extends CommonFolderItemsProps {
42
41
  folders: FolderType[];
43
42
  newFolderParentId: string | undefined;
44
43
  onCancelNewFolder: () => void;
45
- onSaveNewFolder: (name: string, parentId: string) => void;
46
44
  openFolders: string[];
47
45
  parentFolder?: FolderType;
48
46
  children?: ReactNode;
47
+ onCreate: OnCreatedFunc;
48
+ newFolderInput?: NewFolderInputFunc;
49
49
  }
50
50
 
51
51
  const FolderItems = ({
@@ -54,11 +54,12 @@ const FolderItems = ({
54
54
  loading,
55
55
  newFolderParentId,
56
56
  onCancelNewFolder,
57
- onSaveNewFolder,
58
57
  openFolders,
59
58
  type,
60
59
  parentFolder,
61
60
  children,
61
+ onCreate,
62
+ newFolderInput,
62
63
  ...rest
63
64
  }: FolderItemsProps) => (
64
65
  <StyledUL
@@ -101,20 +102,12 @@ const FolderItems = ({
101
102
  type={type}
102
103
  newFolderParentId={newFolderParentId}
103
104
  onCancelNewFolder={onCancelNewFolder}
104
- onSaveNewFolder={onSaveNewFolder}
105
105
  openFolders={openFolders}
106
+ newFolderInput={newFolderInput}
107
+ onCreate={onCreate}
106
108
  {...rest}>
107
109
  {newFolderParentId === id && (
108
- <li role="none">
109
- <FolderNameInput
110
- loading={loading}
111
- level={level}
112
- onCancelNewFolder={onCancelNewFolder}
113
- onSaveNewFolder={onSaveNewFolder}
114
- parentId={newFolderParentId}
115
- type={type}
116
- />
117
- </li>
110
+ <li role="none">{newFolderInput?.({ parentId: id, onClose: onCancelNewFolder, onCreate })}</li>
118
111
  )}
119
112
  </FolderItems>
120
113
  )}