@ndla/ui 20.0.3 → 21.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 (36) hide show
  1. package/es/LearningPaths/LearningPathInformation.js +21 -3
  2. package/es/LearningPaths/LearningPathMenuAsideCopyright.js +17 -4
  3. package/es/TreeStructure/FolderItem.js +72 -51
  4. package/es/TreeStructure/FolderItems.js +33 -61
  5. package/es/TreeStructure/FolderNameInput.js +14 -13
  6. package/es/TreeStructure/TreeStructure.js +80 -96
  7. package/es/TreeStructure/helperFunctions.js +4 -73
  8. package/es/TreeStructure/{TreeStructure.types.js → types.js} +0 -0
  9. package/lib/LearningPaths/LearningPathInformation.js +19 -2
  10. package/lib/LearningPaths/LearningPathMenuAsideCopyright.js +16 -3
  11. package/lib/TreeStructure/FolderItem.d.ts +6 -20
  12. package/lib/TreeStructure/FolderItem.js +74 -51
  13. package/lib/TreeStructure/FolderItems.d.ts +11 -2
  14. package/lib/TreeStructure/FolderItems.js +33 -61
  15. package/lib/TreeStructure/FolderNameInput.js +14 -13
  16. package/lib/TreeStructure/TreeStructure.d.ts +12 -2
  17. package/lib/TreeStructure/TreeStructure.js +78 -94
  18. package/lib/TreeStructure/helperFunctions.d.ts +2 -4
  19. package/lib/TreeStructure/helperFunctions.js +5 -80
  20. package/lib/TreeStructure/index.d.ts +2 -1
  21. package/lib/TreeStructure/types.d.ts +32 -0
  22. package/lib/TreeStructure/{TreeStructure.types.js → types.js} +0 -0
  23. package/lib/index.d.ts +1 -1
  24. package/package.json +3 -2
  25. package/src/LearningPaths/LearningPathInformation.tsx +27 -12
  26. package/src/LearningPaths/LearningPathMenuAsideCopyright.tsx +22 -20
  27. package/src/TreeStructure/FolderItem.tsx +59 -67
  28. package/src/TreeStructure/FolderItems.tsx +30 -50
  29. package/src/TreeStructure/FolderNameInput.tsx +6 -11
  30. package/src/TreeStructure/TreeStructure.tsx +73 -71
  31. package/src/TreeStructure/helperFunctions.ts +3 -37
  32. package/src/TreeStructure/index.ts +2 -1
  33. package/src/TreeStructure/types.ts +37 -0
  34. package/src/index.ts +1 -1
  35. package/lib/TreeStructure/TreeStructure.types.d.ts +0 -61
  36. package/src/TreeStructure/TreeStructure.types.ts +0 -71
@@ -0,0 +1,32 @@
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
+ import { MouseEvent, ReactNode } from 'react';
9
+ import { IFolder } from '@ndla/types-learningpath-api';
10
+ import { MenuItemProps } from '@ndla/button/src';
11
+ export interface FolderType extends IFolder {
12
+ icon?: ReactNode;
13
+ }
14
+ export interface TreeStructureMenuProps extends Omit<MenuItemProps, 'onClick'> {
15
+ onClick: (e: MouseEvent<HTMLDivElement> | undefined, folder: FolderType) => void;
16
+ }
17
+ export interface CommonTreeStructureProps {
18
+ loading?: boolean;
19
+ onSelectFolder?: (id: string) => void;
20
+ openOnFolderClick?: boolean;
21
+ menuItems?: TreeStructureMenuProps[];
22
+ }
23
+ export interface CommonFolderItemsProps extends CommonTreeStructureProps {
24
+ focusedFolderId?: string;
25
+ level: number;
26
+ selectedFolder?: FolderType;
27
+ onCloseFolder: (id: string) => void;
28
+ onOpenFolder: (id: string) => void;
29
+ setFocusedId: (id: string) => void;
30
+ setSelectedFolder: (id: FolderType) => void;
31
+ visibleFolders: string[];
32
+ }
package/lib/index.d.ts CHANGED
@@ -88,4 +88,4 @@ export type { SnackBarItem } from './SnackBar';
88
88
  export { SnackBar } from './SnackBar';
89
89
  export { InfoBlock } from './InfoBlock';
90
90
  export { TreeStructure } from './TreeStructure';
91
- export type { FolderStructureProps, TreeStructureProps } from './TreeStructure';
91
+ export type { FolderType, TreeStructureProps, TreeStructureMenuProps } from './TreeStructure';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ndla/ui",
3
- "version": "20.0.3",
3
+ "version": "21.0.0",
4
4
  "description": "UI component library for NDLA.",
5
5
  "license": "GPL-3.0",
6
6
  "main": "lib/index.js",
@@ -44,6 +44,7 @@
44
44
  "@ndla/switch": "^0.1.9",
45
45
  "@ndla/tabs": "^1.1.13",
46
46
  "@ndla/tooltip": "^2.1.4",
47
+ "@ndla/types-learningpath-api": "^0.0.12",
47
48
  "@ndla/util": "^3.0.0",
48
49
  "@reach/menu-button": "^0.16.2",
49
50
  "@reach/slider": "^0.16.0",
@@ -82,5 +83,5 @@
82
83
  "publishConfig": {
83
84
  "access": "public"
84
85
  },
85
- "gitHead": "fd7915eee936f4d2450c1263e4830a7bda29d49a"
86
+ "gitHead": "57a015c6fe4a2106bb88d0f2ebea44592aa4d29e"
86
87
  }
@@ -8,7 +8,8 @@
8
8
 
9
9
  import React from 'react';
10
10
  import styled from '@emotion/styled';
11
- import { fonts, spacing, spacingUnit, breakpoints, mq } from '@ndla/core';
11
+ import { fonts, spacing, spacingUnit, breakpoints, mq, colors } from '@ndla/core';
12
+ import { getLicenseByAbbreviation, LicenseByline } from '@ndla/licenses';
12
13
 
13
14
  type StyledWrapperProps = {
14
15
  invertedStyle?: boolean;
@@ -50,6 +51,17 @@ const StyledWrapper = styled.div<StyledWrapperProps>`
50
51
  }
51
52
  `;
52
53
 
54
+ const LicenseWrapper = styled.div`
55
+ ul {
56
+ margin-left: 0;
57
+ margin-bottom: ${spacing.small};
58
+ }
59
+ `;
60
+
61
+ const StyledHeader = styled.h1`
62
+ margin-bottom: ${spacing.small};
63
+ `;
64
+
53
65
  interface Props {
54
66
  description?: string;
55
67
  title: string;
@@ -59,14 +71,17 @@ interface Props {
59
71
  };
60
72
  }
61
73
 
62
- export const LearningPathInformation = ({ description, title, license, invertedStyle }: Props) => (
63
- <section className="o-wrapper">
64
- <StyledWrapper invertedStyle={invertedStyle} className="c-article">
65
- <div>
66
- <h1>{title}</h1>
67
- {license && license.license}
68
- </div>
69
- {description && <div dangerouslySetInnerHTML={{ __html: description }} />}
70
- </StyledWrapper>
71
- </section>
72
- );
74
+ export const LearningPathInformation = ({ description, title, license, invertedStyle }: Props) => {
75
+ const { rights } = getLicenseByAbbreviation(license?.license || '', 'nb');
76
+ return (
77
+ <section className="o-wrapper">
78
+ <StyledWrapper invertedStyle={invertedStyle} className="c-article">
79
+ <LicenseWrapper>
80
+ <StyledHeader>{title}</StyledHeader>
81
+ <LicenseByline licenseRights={rights} color={colors.brand.tertiary} />
82
+ </LicenseWrapper>
83
+ {description && <div dangerouslySetInnerHTML={{ __html: description }} />}
84
+ </StyledWrapper>
85
+ </section>
86
+ );
87
+ };
@@ -9,22 +9,20 @@
9
9
  import React from 'react';
10
10
  import styled from '@emotion/styled';
11
11
  import { User } from '@ndla/icons/common';
12
- import { spacing, fonts } from '@ndla/core';
12
+ import { spacing, fonts, colors } from '@ndla/core';
13
+ import { getLicenseByAbbreviation, LicenseByline } from '@ndla/licenses';
13
14
 
14
15
  const StyledLearningPathDetails = styled.div`
15
16
  ${fonts.sizes(14, 1.1)};
16
17
  font-weight: ${fonts.weight.normal};
17
- margin: 0;
18
+ `;
19
+
20
+ const UserLine = styled.div`
18
21
  display: flex;
19
- align-items: flex-start;
20
- justify-items: flex-start;
21
22
  margin-bottom: ${spacing.xsmall};
22
- p {
23
- margin: 0;
24
- padding-left: ${spacing.xsmall};
25
- }
23
+
26
24
  span {
27
- display: block;
25
+ margin-left: ${spacing.xsmall};
28
26
  }
29
27
  `;
30
28
 
@@ -40,16 +38,20 @@ type Props = {
40
38
  };
41
39
  };
42
40
 
43
- const LearningPathMenuAsideCopyright = ({ copyright }: Props) => (
44
- <StyledLearningPathDetails>
45
- <User />
46
- <p>
47
- {copyright.contributors.map((contributor) => (
48
- <span key={contributor.name}>{contributor.name}</span>
49
- ))}
50
- <span>{copyright.license.license}</span>
51
- </p>
52
- </StyledLearningPathDetails>
53
- );
41
+ const LearningPathMenuAsideCopyright = ({ copyright }: Props) => {
42
+ const { rights } = getLicenseByAbbreviation(copyright.license.license || '', 'nb');
43
+ return (
44
+ <StyledLearningPathDetails>
45
+ <UserLine>
46
+ <User />
47
+ {copyright.contributors.map((contributor) => (
48
+ <span key={contributor.name}>{contributor.name}</span>
49
+ ))}
50
+ </UserLine>
51
+
52
+ <LicenseByline licenseRights={rights} color={colors.brand.tertiary} />
53
+ </StyledLearningPathDetails>
54
+ );
55
+ };
54
56
 
55
57
  export default LearningPathMenuAsideCopyright;
@@ -6,13 +6,14 @@
6
6
  *
7
7
  */
8
8
 
9
- import React, { KeyboardEvent, useEffect, useRef } from 'react';
9
+ import React, { KeyboardEvent, MouseEvent, useEffect, useRef } from 'react';
10
10
  import styled from '@emotion/styled';
11
11
  import { ArrowDropDown } from '@ndla/icons/common';
12
+ import { MenuButton } from '@ndla/button';
12
13
  import { FolderOutlined } from '@ndla/icons/contentType';
13
14
  import { colors, spacing, misc, animations } from '@ndla/core';
14
15
  import SafeLink from '@ndla/safelink';
15
- import { SetFocusedFolderId, FolderChildFuncType } from './TreeStructure.types';
16
+ import { CommonFolderItemsProps, FolderType } from './types';
16
17
  import { arrowNavigation } from './arrowNavigation';
17
18
 
18
19
  const OpenButton = styled.button<{ isOpen: boolean }>`
@@ -39,10 +40,10 @@ const FolderItemWrapper = styled.div`
39
40
  align-items: center;
40
41
  `;
41
42
 
42
- const WrapperForFolderChild = styled.div<{ marked: boolean }>`
43
+ const WrapperForFolderChild = styled.div<{ selected?: boolean }>`
43
44
  position: absolute;
44
45
  right: ${spacing.xsmall};
45
- opacity: ${({ marked }) => (marked ? 1 : 0.25)};
46
+ opacity: ${({ selected }) => (selected ? 1 : 0.25)};
46
47
  &:hover,
47
48
  &:focus,
48
49
  &:focus-within {
@@ -50,16 +51,20 @@ const WrapperForFolderChild = styled.div<{ marked: boolean }>`
50
51
  }
51
52
  `;
52
53
 
53
- const FolderName = styled('button', { shouldForwardProp: (name) => !['marked', 'noArrow'].includes(name) })<{
54
- marked: boolean;
54
+ const shouldForwardProp = (name: string) => !['selected', 'noArrow'].includes(name);
55
+
56
+ interface FolderNameProps {
57
+ selected?: boolean;
55
58
  noArrow?: boolean;
56
- }>`
59
+ }
60
+
61
+ const FolderName = styled('button', { shouldForwardProp })<FolderNameProps>`
57
62
  line-height: 1;
58
- background: ${({ marked }) => (marked ? colors.brand.lighter : 'transparent')};
63
+ background: ${({ selected }) => (selected ? colors.brand.lighter : 'transparent')};
59
64
  color: ${colors.text.primary};
60
65
  &:hover,
61
66
  &:focus {
62
- background: ${({ marked }) => (marked ? colors.brand.light : colors.brand.lightest)};
67
+ background: ${({ selected }) => (selected ? colors.brand.light : colors.brand.lightest)};
63
68
  color: ${colors.brand.primary};
64
69
  + ${WrapperForFolderChild} {
65
70
  opacity: 1;
@@ -82,52 +87,40 @@ const FolderName = styled('button', { shouldForwardProp: (name) => !['marked', '
82
87
 
83
88
  const FolderNameLink = FolderName.withComponent(SafeLink);
84
89
 
85
- interface Props {
86
- name: string;
87
- id: string;
88
- level: number;
89
- onCloseFolder: (id: string) => void;
90
- onOpenFolder: (id: string) => void;
91
- onMarkFolder: (id: string) => void;
92
- onSelectFolder?: (id: string) => void;
93
- isOpen: boolean;
94
- markedFolderId?: string;
95
- focusedFolderId?: string;
96
- visibleFolders: string[];
97
- loading?: boolean;
98
- openOnFolderClick?: boolean;
90
+ interface Props extends CommonFolderItemsProps {
99
91
  hideArrow?: boolean;
100
- setFocusedFolderId: SetFocusedFolderId;
101
- icon?: React.ReactNode;
92
+ isOpen: boolean;
93
+ folder: FolderType;
102
94
  noPaddingWhenArrowIsHidden?: boolean;
103
- folderChild?: FolderChildFuncType;
104
95
  }
105
96
 
106
97
  const FolderItem = ({
98
+ focusedFolderId,
99
+ menuItems,
107
100
  hideArrow,
108
- loading,
101
+ folder,
102
+ isOpen,
109
103
  level,
110
- name,
111
- id,
112
- visibleFolders,
104
+ loading,
105
+ selectedFolder,
106
+ noPaddingWhenArrowIsHidden,
113
107
  onCloseFolder,
114
108
  onOpenFolder,
115
- onMarkFolder,
116
109
  onSelectFolder,
117
- isOpen,
118
- markedFolderId,
119
- focusedFolderId,
120
110
  openOnFolderClick,
121
- setFocusedFolderId,
122
- icon,
123
- noPaddingWhenArrowIsHidden,
124
- folderChild,
111
+ setFocusedId,
112
+ setSelectedFolder,
113
+ visibleFolders,
125
114
  }: Props) => {
115
+ const { id, icon, name } = folder;
126
116
  const ref = useRef<HTMLButtonElement & HTMLAnchorElement>(null);
127
- const marked = markedFolderId === id;
117
+ const selected = selectedFolder && selectedFolder.id === id;
118
+ const focused = focusedFolderId === id;
128
119
 
129
- const handleMarkFolder = () => {
130
- onMarkFolder(id);
120
+ const handleClickFolder = () => {
121
+ setSelectedFolder(folder);
122
+ setFocusedId(id);
123
+ onSelectFolder?.(id);
131
124
  if (openOnFolderClick) {
132
125
  if (isOpen) {
133
126
  onCloseFolder(id);
@@ -139,12 +132,20 @@ const FolderItem = ({
139
132
 
140
133
  useEffect(() => {
141
134
  if (focusedFolderId === id) {
142
- if (ref.current) {
143
- ref.current.focus();
144
- }
135
+ ref.current?.focus();
145
136
  }
146
137
  }, [focusedFolderId, ref, id]);
147
138
 
139
+ const actions = menuItems?.map((item) => {
140
+ const { onClick } = item;
141
+ return {
142
+ ...item,
143
+ onClick: (e?: MouseEvent<HTMLDivElement>) => onClick(e, folder),
144
+ };
145
+ });
146
+
147
+ const linkPath = `/minndla${level > 1 ? '/folders' : ''}/${id}`;
148
+
148
149
  return (
149
150
  <FolderItemWrapper>
150
151
  {!hideArrow && (
@@ -160,24 +161,19 @@ const FolderItem = ({
160
161
  <>
161
162
  <FolderName
162
163
  ref={ref}
163
- onKeyDown={(e) => arrowNavigation(e, id, visibleFolders, setFocusedFolderId, onOpenFolder, onCloseFolder)}
164
+ onKeyDown={(e) => arrowNavigation(e, id, visibleFolders, setFocusedId, onOpenFolder, onCloseFolder)}
164
165
  noArrow={hideArrow && !noPaddingWhenArrowIsHidden}
165
- tabIndex={marked ? 0 : -1}
166
- marked={marked}
166
+ tabIndex={selected || focused ? 0 : -1}
167
+ selected={selected}
167
168
  disabled={loading}
168
- onFocus={() => {
169
- setFocusedFolderId(id);
170
- }}
171
- onClick={() => {
172
- handleMarkFolder();
173
- onSelectFolder(id);
174
- }}>
169
+ onFocus={() => setFocusedId(id)}
170
+ onClick={handleClickFolder}>
175
171
  {icon || <FolderOutlined />}
176
172
  {name}
177
173
  </FolderName>
178
- {folderChild && (
179
- <WrapperForFolderChild marked={marked}>
180
- {folderChild(id, marked || id === focusedFolderId ? 0 : -1)}
174
+ {actions && (
175
+ <WrapperForFolderChild selected={selected}>
176
+ <MenuButton size="xsmall" menuItems={actions} tabIndex={selected || id === focusedFolderId ? 0 : -1} />
181
177
  </WrapperForFolderChild>
182
178
  )}
183
179
  </>
@@ -185,18 +181,14 @@ const FolderItem = ({
185
181
  <FolderNameLink
186
182
  ref={ref}
187
183
  onKeyDown={(e: KeyboardEvent<HTMLElement>) =>
188
- arrowNavigation(e, id, visibleFolders, setFocusedFolderId, onOpenFolder, onCloseFolder)
184
+ arrowNavigation(e, id, visibleFolders, setFocusedId, onOpenFolder, onCloseFolder)
189
185
  }
190
186
  noArrow={hideArrow}
191
- to={loading ? '' : `/minndla/${level > 1 ? 'folders/' : ''}${id}`}
192
- tabIndex={marked || level === 1 ? 0 : -1}
193
- marked={marked}
194
- onFocus={() => {
195
- setFocusedFolderId(id);
196
- }}
197
- onClick={() => {
198
- handleMarkFolder();
199
- }}>
187
+ to={loading ? '' : linkPath}
188
+ tabIndex={selected || focused || level === 1 ? 0 : -1}
189
+ selected={selected}
190
+ onFocus={() => setFocusedId(id)}
191
+ onClick={handleClickFolder}>
200
192
  {icon || <FolderOutlined />}
201
193
  {name}
202
194
  </FolderNameLink>
@@ -11,7 +11,7 @@ import styled from '@emotion/styled';
11
11
  import { animations, spacing } from '@ndla/core';
12
12
  import FolderItem from './FolderItem';
13
13
  import FolderNameInput from './FolderNameInput';
14
- import { FolderItemsProps } from './TreeStructure.types';
14
+ import { CommonFolderItemsProps, FolderType } from './types';
15
15
 
16
16
  const StyledUL = styled.ul<{ firstLevel?: boolean }>`
17
17
  ${animations.fadeInLeft(animations.durations.fast)};
@@ -30,85 +30,65 @@ const StyledLI = styled.li`
30
30
  padding: 0;
31
31
  `;
32
32
 
33
+ export interface FolderItemsProps extends CommonFolderItemsProps {
34
+ folders: FolderType[];
35
+ editable?: boolean;
36
+ maximumLevelsOfFoldersAllowed: number;
37
+ newFolderParentId: string | undefined;
38
+ onCancelNewFolder: () => void;
39
+ onSaveNewFolder: (name: string, parentId: string) => void;
40
+ openFolders: string[];
41
+ }
42
+
33
43
  const FolderItems = ({
34
- loading,
44
+ editable,
35
45
  folders,
36
46
  level,
37
- editable,
38
- onSelectFolder,
39
- onCloseFolder,
40
- onOpenFolder,
41
- onCreateNewFolder,
47
+ loading,
48
+ maximumLevelsOfFoldersAllowed,
49
+ newFolderParentId,
42
50
  onCancelNewFolder,
43
51
  onSaveNewFolder,
44
- newFolderParentId,
45
- visibleFolders,
46
52
  openFolders,
47
- markedFolderId,
48
- onMarkFolder,
49
- openOnFolderClick,
50
- focusedFolderId,
51
- setFocusedFolderId,
52
- folderChild,
53
- maximumLevelsOfFoldersAllowed,
53
+ ...rest
54
54
  }: FolderItemsProps) => (
55
55
  <StyledUL role="group" firstLevel={level === 1}>
56
- {folders.map(({ name, subfolders, id, icon }, _index) => {
56
+ {folders.map((folder) => {
57
+ const { subfolders, id } = folder;
57
58
  const isOpen = openFolders?.includes(id);
58
59
  return (
59
60
  <StyledLI key={id} role="treeitem">
60
61
  <div>
61
62
  <FolderItem
63
+ hideArrow={subfolders?.length === 0 || level > maximumLevelsOfFoldersAllowed}
64
+ folder={folder}
65
+ isOpen={isOpen}
62
66
  level={level}
63
- icon={icon}
64
- onSelectFolder={onSelectFolder}
65
- openOnFolderClick={openOnFolderClick}
66
67
  loading={loading}
67
- isOpen={isOpen}
68
- id={id}
69
- visibleFolders={visibleFolders}
70
- name={name}
71
- markedFolderId={markedFolderId}
72
- focusedFolderId={focusedFolderId}
73
- onMarkFolder={onMarkFolder}
74
- onCloseFolder={onCloseFolder}
75
- onOpenFolder={onOpenFolder}
76
- hideArrow={subfolders?.length === 0 || level > maximumLevelsOfFoldersAllowed}
77
68
  noPaddingWhenArrowIsHidden={editable && level === 1 && subfolders?.length === 0}
78
- setFocusedFolderId={setFocusedFolderId}
79
- folderChild={folderChild}
69
+ {...rest}
80
70
  />
81
71
  </div>
82
72
  {newFolderParentId === id && (
83
73
  <FolderNameInput
84
- parentId={newFolderParentId}
85
74
  loading={loading}
86
75
  onCancelNewFolder={onCancelNewFolder}
87
76
  onSaveNewFolder={onSaveNewFolder}
77
+ parentId={newFolderParentId}
88
78
  />
89
79
  )}
90
80
  {subfolders && isOpen && (
91
81
  <FolderItems
92
- onSelectFolder={onSelectFolder}
93
- loading={loading}
94
- newFolderParentId={newFolderParentId}
95
- visibleFolders={visibleFolders}
96
- openFolders={openFolders}
97
- level={level + 1}
98
82
  editable={editable}
99
83
  folders={subfolders}
100
- onCloseFolder={onCloseFolder}
101
- onOpenFolder={onOpenFolder}
102
- onCreateNewFolder={onCreateNewFolder}
103
- onSaveNewFolder={onSaveNewFolder}
104
- onCancelNewFolder={onCancelNewFolder}
105
- markedFolderId={markedFolderId}
106
- onMarkFolder={onMarkFolder}
107
- openOnFolderClick={openOnFolderClick}
108
- focusedFolderId={focusedFolderId}
109
- setFocusedFolderId={setFocusedFolderId}
110
- folderChild={folderChild}
84
+ level={level + 1}
85
+ loading={loading}
111
86
  maximumLevelsOfFoldersAllowed={maximumLevelsOfFoldersAllowed}
87
+ newFolderParentId={newFolderParentId}
88
+ onCancelNewFolder={onCancelNewFolder}
89
+ onSaveNewFolder={onSaveNewFolder}
90
+ openFolders={openFolders}
91
+ {...rest}
112
92
  />
113
93
  )}
114
94
  </StyledLI>
@@ -6,7 +6,7 @@
6
6
  *
7
7
  */
8
8
 
9
- import React, { useEffect, useState, useRef } from 'react';
9
+ import React, { useEffect, useState, useRef, ChangeEvent, KeyboardEvent } from 'react';
10
10
  import styled from '@emotion/styled';
11
11
  import { FolderOutlined } from '@ndla/icons/contentType';
12
12
  import { ArrowDropDown as ArrowDropDownRaw } from '@ndla/icons/common';
@@ -65,11 +65,9 @@ const FolderNameInput = ({ onSaveNewFolder, parentId, onCancelNewFolder, loading
65
65
  const inputRef = useRef<HTMLInputElement>(null);
66
66
 
67
67
  useEffect(() => {
68
- if (inputRef.current) {
69
- inputRef.current.select();
70
- if (isMobile) {
71
- inputRef.current.scrollIntoView({ behavior: 'smooth' });
72
- }
68
+ inputRef.current?.select();
69
+ if (isMobile) {
70
+ inputRef.current?.scrollIntoView({ behavior: 'smooth' });
73
71
  }
74
72
  }, []);
75
73
 
@@ -85,7 +83,7 @@ const FolderNameInput = ({ onSaveNewFolder, parentId, onCancelNewFolder, loading
85
83
  disabled={loading}
86
84
  value={name}
87
85
  onBlur={() => onCancelNewFolder()}
88
- onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>) => {
86
+ onKeyDown={(e: KeyboardEvent<HTMLInputElement>) => {
89
87
  if (e.key === 'Escape') {
90
88
  onCancelNewFolder();
91
89
  } else if (e.key === 'Enter' || e.key === 'Tab') {
@@ -93,10 +91,7 @@ const FolderNameInput = ({ onSaveNewFolder, parentId, onCancelNewFolder, loading
93
91
  onSaveNewFolder(name, parentId);
94
92
  }
95
93
  }}
96
- onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
97
- const target = e.target;
98
- setName(target.value);
99
- }}
94
+ onChange={(e: ChangeEvent<HTMLInputElement>) => setName(e.target.value)}
100
95
  />
101
96
  {loading && <Spinner size="small" />}
102
97
  </InputWrapper>