@ndla/ui 30.9.0 → 32.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 (155) hide show
  1. package/README.md +4 -0
  2. package/es/Animation/DisplayOnPageYOffset.js +1 -1
  3. package/es/Article/Article.js +3 -3
  4. package/es/Filter/FilterListPhone.js +1 -1
  5. package/es/NDLAFilm/AllMoviesAlphabetically.js +12 -12
  6. package/es/ResourceBox/ResourceBox.js +9 -11
  7. package/es/TopicMenu/TopicMenu.js +2 -2
  8. package/es/TreeStructure/AddFolderButton.js +2 -2
  9. package/es/TreeStructure/ComboboxButton.js +2 -2
  10. package/es/TreeStructure/FolderItem.js +11 -10
  11. package/es/TreeStructure/FolderItems.js +28 -37
  12. package/es/TreeStructure/TreeStructure.js +8 -8
  13. package/es/User/parseUserObject.js +1 -1
  14. package/lib/Animation/DisplayOnPageYOffset.js +2 -2
  15. package/lib/Article/Article.d.ts +5 -5
  16. package/lib/Article/Article.js +4 -4
  17. package/lib/Article/ArticleAccessMessage.d.ts +1 -1
  18. package/lib/Article/ArticleByline.d.ts +3 -3
  19. package/lib/Article/ArticleContent.d.ts +1 -1
  20. package/lib/Article/ArticleFootNotes.d.ts +1 -1
  21. package/lib/Article/ArticleHeaderWrapper.d.ts +2 -2
  22. package/lib/Article/ArticleNotions.d.ts +2 -2
  23. package/lib/Article/ArticleSideBar.d.ts +1 -1
  24. package/lib/AudioPlayer/AudioPlayer.d.ts +1 -1
  25. package/lib/AudioPlayer/Controls.d.ts +1 -1
  26. package/lib/AudioPlayer/SpeechControl.d.ts +1 -1
  27. package/lib/BannerCard/BannerCard.d.ts +2 -2
  28. package/lib/BlogPosts/BlogPost.d.ts +1 -1
  29. package/lib/Breadcrumblist/Breadcrumblist.d.ts +2 -2
  30. package/lib/CompetenceGoalTab/CompetenceGoalTab.d.ts +1 -1
  31. package/lib/CompetenceGoalTab/CompetenceItem.d.ts +5 -5
  32. package/lib/CompetenceGoalTab/SearchButton.d.ts +1 -1
  33. package/lib/ComponentCursor/ComponentCursor.d.ts +1 -1
  34. package/lib/CreatedBy/CreatedBy.d.ts +1 -1
  35. package/lib/ErrorMessage/ErrorResourceAccessDenied.d.ts +1 -1
  36. package/lib/Figure/Figure.d.ts +1 -1
  37. package/lib/Filter/FilterButtons.d.ts +2 -2
  38. package/lib/Filter/FilterListPhone.js +2 -2
  39. package/lib/Footer/EditorName.d.ts +1 -1
  40. package/lib/Footer/Footer.d.ts +1 -1
  41. package/lib/Footer/FooterLinks.d.ts +1 -1
  42. package/lib/Footer/FooterPrivacy.d.ts +1 -1
  43. package/lib/Footer/FooterText.d.ts +1 -1
  44. package/lib/Frontpage/FrontpageAllSubjects.d.ts +3 -3
  45. package/lib/Frontpage/FrontpageFilm.d.ts +1 -1
  46. package/lib/Frontpage/FrontpageInfo.d.ts +1 -1
  47. package/lib/Frontpage/FrontpageMultidisciplinarySubject.d.ts +1 -1
  48. package/lib/Frontpage/FrontpageProgramMenu.d.ts +1 -1
  49. package/lib/Frontpage/FrontpageSearch.d.ts +1 -1
  50. package/lib/Frontpage/FrontpageToolbox.d.ts +1 -1
  51. package/lib/Hero/Hero.d.ts +1 -1
  52. package/lib/LanguageSelector/LanguageSelector.d.ts +1 -1
  53. package/lib/LanguageSelector/LanguageSelectorContent.d.ts +1 -1
  54. package/lib/LearningPaths/LearningPathMenu.d.ts +1 -1
  55. package/lib/LearningPaths/LearningPathMenuAside.d.ts +1 -1
  56. package/lib/LearningPaths/LearningPathMenuAsideCopyright.d.ts +1 -1
  57. package/lib/LearningPaths/LearningPathMenuContent.d.ts +1 -1
  58. package/lib/LearningPaths/LearningPathMenuModalWrapper.d.ts +1 -1
  59. package/lib/LearningPaths/LearningPathMobileStepInfo.d.ts +1 -1
  60. package/lib/LearningPaths/LearningPathSticky.d.ts +1 -1
  61. package/lib/Messages/MessageBox.d.ts +1 -1
  62. package/lib/Messages/MessageBoxTag.d.ts +1 -1
  63. package/lib/MultidisciplinarySubject/List.d.ts +1 -1
  64. package/lib/MultidisciplinarySubject/ListItem.d.ts +1 -1
  65. package/lib/MultidisciplinarySubject/MultidisciplinarySubject.d.ts +1 -1
  66. package/lib/MultidisciplinarySubject/MultidisciplinarySubjectHeader.d.ts +3 -3
  67. package/lib/MyNdla/Resource/Folder.d.ts +1 -1
  68. package/lib/MyNdla/Resource/FolderInput.d.ts +1 -1
  69. package/lib/NDLAFilm/AllMoviesAlphabetically.js +13 -13
  70. package/lib/Navigation/NavigationBox.d.ts +3 -3
  71. package/lib/Navigation/NavigationHeading.d.ts +1 -1
  72. package/lib/Navigation/NavigationTopicAbout.d.ts +1 -1
  73. package/lib/Notion/Notion.d.ts +1 -1
  74. package/lib/Notion/NotionVisualElement.d.ts +1 -1
  75. package/lib/Programme/Programme.d.ts +1 -1
  76. package/lib/Programme/ProgrammeSubjects.d.ts +2 -2
  77. package/lib/Resource/resourceComponents.d.ts +1 -1
  78. package/lib/ResourceBox/ResourceBox.d.ts +2 -1
  79. package/lib/ResourceBox/ResourceBox.js +9 -11
  80. package/lib/ResourceGroup/ResourceGroup.d.ts +1 -1
  81. package/lib/ResourceGroup/ResourceItem.d.ts +1 -1
  82. package/lib/ResourceGroup/ResourceList.d.ts +1 -1
  83. package/lib/Search/ContentTypeResult.d.ts +1 -1
  84. package/lib/Search/ContentTypeResultStyles.d.ts +2 -2
  85. package/lib/Search/LoadingWrapper.d.ts +1 -1
  86. package/lib/Search/SearchResultSleeve.d.ts +1 -1
  87. package/lib/SearchTypeResult/ActiveFilterContent.d.ts +2 -2
  88. package/lib/SearchTypeResult/ActiveFilters.d.ts +1 -1
  89. package/lib/SearchTypeResult/PopupFilter.d.ts +2 -2
  90. package/lib/SearchTypeResult/ResultNavigation.d.ts +1 -1
  91. package/lib/SearchTypeResult/SearchFieldHeader.d.ts +1 -1
  92. package/lib/SearchTypeResult/SearchFilterContent.d.ts +1 -1
  93. package/lib/SearchTypeResult/SearchHeader.d.ts +1 -1
  94. package/lib/SearchTypeResult/SearchItem.d.ts +2 -2
  95. package/lib/SearchTypeResult/SearchItems.d.ts +1 -1
  96. package/lib/SearchTypeResult/SearchNotionItem.d.ts +1 -1
  97. package/lib/SearchTypeResult/SearchNotionsResult.d.ts +1 -1
  98. package/lib/SearchTypeResult/SearchSubjectItem.d.ts +2 -2
  99. package/lib/SearchTypeResult/SearchSubjectResult.d.ts +1 -1
  100. package/lib/SearchTypeResult/SearchTypeHeader.d.ts +2 -2
  101. package/lib/SearchTypeResult/SearchTypeResult.d.ts +2 -2
  102. package/lib/SearchTypeResult/SearchViewType.d.ts +1 -1
  103. package/lib/SearchTypeResult/components/ItemContexts.d.ts +2 -2
  104. package/lib/SearchTypeResult/components/ItemResourceHeader.d.ts +1 -1
  105. package/lib/SearchTypeResult/components/ItemTopicHeader.d.ts +1 -1
  106. package/lib/SearchTypeResult/components/SubjectFilters.d.ts +4 -4
  107. package/lib/Subject/SubjectBanner.d.ts +2 -2
  108. package/lib/Subject/SubjectHeader.d.ts +1 -1
  109. package/lib/Topic/Topic.d.ts +2 -2
  110. package/lib/TopicMenu/TopicMenu.js +3 -3
  111. package/lib/TreeStructure/AddFolderButton.d.ts +2 -2
  112. package/lib/TreeStructure/AddFolderButton.js +2 -2
  113. package/lib/TreeStructure/ComboboxButton.d.ts +7 -6
  114. package/lib/TreeStructure/ComboboxButton.js +2 -2
  115. package/lib/TreeStructure/FolderItem.d.ts +5 -3
  116. package/lib/TreeStructure/FolderItem.js +11 -10
  117. package/lib/TreeStructure/FolderItems.d.ts +4 -3
  118. package/lib/TreeStructure/FolderItems.js +28 -36
  119. package/lib/TreeStructure/TreeStructure.d.ts +3 -2
  120. package/lib/TreeStructure/TreeStructure.js +11 -11
  121. package/lib/TreeStructure/arrowNavigation.d.ts +2 -2
  122. package/lib/TreeStructure/helperFunctions.d.ts +3 -2
  123. package/lib/TreeStructure/index.d.ts +0 -1
  124. package/lib/TreeStructure/types.d.ts +8 -12
  125. package/lib/User/AuthModal.d.ts +1 -1
  126. package/lib/User/apiTypes.d.ts +3 -3
  127. package/lib/User/parseUserObject.d.ts +1 -1
  128. package/lib/User/parseUserObject.js +3 -2
  129. package/lib/index.d.ts +1 -1
  130. package/lib/locale/LocaleProvider.d.ts +1 -1
  131. package/lib/types.d.ts +11 -11
  132. package/package.json +10 -10
  133. package/src/Animation/DisplayOnPageYOffset.tsx +1 -1
  134. package/src/Article/Article.tsx +1 -1
  135. package/src/Filter/FilterListPhone.tsx +1 -1
  136. package/src/NDLAFilm/AllMoviesAlphabetically.tsx +1 -1
  137. package/src/ResourceBox/ResourceBox.tsx +3 -4
  138. package/src/TopicMenu/TopicMenu.jsx +1 -1
  139. package/src/TreeStructure/AddFolderButton.tsx +2 -2
  140. package/src/TreeStructure/ComboboxButton.tsx +7 -6
  141. package/src/TreeStructure/FolderItem.tsx +10 -7
  142. package/src/TreeStructure/FolderItems.tsx +31 -36
  143. package/src/TreeStructure/TreeStructure.tsx +7 -7
  144. package/src/TreeStructure/arrowNavigation.ts +5 -5
  145. package/src/TreeStructure/helperFunctions.ts +4 -3
  146. package/src/TreeStructure/index.ts +0 -1
  147. package/src/TreeStructure/types.ts +5 -10
  148. package/src/User/parseUserObject.ts +1 -1
  149. package/src/index.ts +1 -1
  150. package/es/LetterFilter/LetterFilter.stories.js +0 -44
  151. package/es/TreeStructure/NavigationLink.js +0 -91
  152. package/lib/LetterFilter/LetterFilter.stories.js +0 -45
  153. package/lib/TreeStructure/NavigationLink.d.ts +0 -14
  154. package/lib/TreeStructure/NavigationLink.js +0 -93
  155. package/src/TreeStructure/NavigationLink.tsx +0 -107
package/lib/types.d.ts CHANGED
@@ -7,18 +7,18 @@
7
7
  */
8
8
  import { ReactNode } from 'react';
9
9
  declare const locales: readonly ["nb", "nn", "en", "se"];
10
- export declare type Locale = typeof locales[number];
11
- export declare type Link = {
10
+ export type Locale = typeof locales[number];
11
+ export type Link = {
12
12
  text: string;
13
13
  to: string;
14
14
  };
15
- export declare type Messages = {
15
+ export type Messages = {
16
16
  closeSearchLabel: string;
17
17
  };
18
- declare type ResourceTypes = {
18
+ type ResourceTypes = {
19
19
  name: string;
20
20
  };
21
- export declare type Resource = {
21
+ export type Resource = {
22
22
  id: string;
23
23
  name: string;
24
24
  contentUri?: string;
@@ -62,7 +62,7 @@ export interface Article {
62
62
  copyright: Copyright;
63
63
  published: string;
64
64
  }
65
- export declare type SearchResult = {
65
+ export type SearchResult = {
66
66
  title: string;
67
67
  contentType: string;
68
68
  resources: Array<Resource>;
@@ -72,22 +72,22 @@ export interface ContentTypeResultType {
72
72
  contentType?: string;
73
73
  resources: Array<Resource>;
74
74
  }
75
- export declare type subjectProp = {
75
+ export type subjectProp = {
76
76
  text: string;
77
77
  url: string;
78
78
  yearInfo?: string;
79
79
  beta?: boolean;
80
80
  };
81
- export declare type category = {
81
+ export type category = {
82
82
  name: string;
83
83
  subjects: Array<subjectProp>;
84
84
  };
85
- export declare type elementRectType = {
85
+ export type elementRectType = {
86
86
  fromX: number;
87
87
  fromY: number;
88
88
  fromScale: number;
89
89
  };
90
- export declare type CompetenceGoalsItemType = {
90
+ export type CompetenceGoalsItemType = {
91
91
  id: string;
92
92
  title: string;
93
93
  goals: {
@@ -98,7 +98,7 @@ export declare type CompetenceGoalsItemType = {
98
98
  selected?: boolean;
99
99
  isOembed?: boolean;
100
100
  };
101
- export declare type NotionMedia = {
101
+ export type NotionMedia = {
102
102
  type: 'video' | 'other';
103
103
  element: ReactNode;
104
104
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ndla/ui",
3
- "version": "30.9.0",
3
+ "version": "32.0.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/article-scripts": "^3.0.11",
35
- "@ndla/button": "^6.0.4",
34
+ "@ndla/article-scripts": "^3.0.12",
35
+ "@ndla/button": "^6.0.5",
36
36
  "@ndla/carousel": "^2.0.8",
37
37
  "@ndla/core": "^3.0.3",
38
- "@ndla/forms": "^4.0.16",
39
- "@ndla/hooks": "^1.1.15",
38
+ "@ndla/forms": "^4.0.17",
39
+ "@ndla/hooks": "^1.1.16",
40
40
  "@ndla/icons": "^2.0.8",
41
41
  "@ndla/licenses": "^6.0.10",
42
42
  "@ndla/modal": "^2.1.3",
43
- "@ndla/notion": "^4.0.18",
44
- "@ndla/safelink": "^3.0.16",
43
+ "@ndla/notion": "^4.0.19",
44
+ "@ndla/safelink": "^3.0.17",
45
45
  "@ndla/switch": "^1.0.3",
46
- "@ndla/tabs": "^2.0.11",
46
+ "@ndla/tabs": "^2.0.12",
47
47
  "@ndla/tooltip": "^3.0.6",
48
48
  "@ndla/types-learningpath-api": "^0.0.17",
49
49
  "@ndla/util": "^3.1.9",
@@ -53,7 +53,6 @@
53
53
  "html-react-parser": "^0.14.1",
54
54
  "i18next-browser-languagedetector": "^6.1.1",
55
55
  "invariant": "^2.2.3",
56
- "lodash": "^4.17.20",
57
56
  "react-bem-helper": "1.4.1",
58
57
  "react-device-detect": "^2.1.2",
59
58
  "react-select": "^5.4.0",
@@ -66,6 +65,7 @@
66
65
  "@emotion/react": "^11.10.4",
67
66
  "@emotion/styled": "^11.10.4",
68
67
  "i18next": "^21.9.2",
68
+ "lodash": "^4.17.20",
69
69
  "prop-types": "^15.8.1",
70
70
  "react": "^16.8.4 || ^17.0.0",
71
71
  "react-i18next": "^11.18.6",
@@ -84,5 +84,5 @@
84
84
  "publishConfig": {
85
85
  "access": "public"
86
86
  },
87
- "gitHead": "68b1327bb5950eee8a41227b3b48589c7d428bd7"
87
+ "gitHead": "1cc4d04cd592bdf11d2d50082cd7a4bf77a5b2a6"
88
88
  }
@@ -8,7 +8,7 @@
8
8
 
9
9
  import React, { Component, ReactNode } from 'react';
10
10
  import PropTypes from 'prop-types';
11
- import { throttle } from 'lodash';
11
+ import throttle from 'lodash/throttle';
12
12
  import Fade from './Fade';
13
13
 
14
14
  interface Props {
@@ -8,7 +8,7 @@
8
8
 
9
9
  import React, { ComponentType, ReactNode, useEffect, useRef, useState, forwardRef } from 'react';
10
10
  import BEMHelper from 'react-bem-helper';
11
- import { isString } from 'lodash';
11
+ import isString from 'lodash/isString';
12
12
  import parse from 'html-react-parser';
13
13
  import styled from '@emotion/styled';
14
14
 
@@ -10,7 +10,7 @@ import React, { ChangeEvent, useEffect, useState } from 'react';
10
10
  import { ChevronDown, ChevronUp } from '@ndla/icons/common';
11
11
  import Modal, { ModalHeader, ModalBody, ModalCloseButton } from '@ndla/modal';
12
12
  import Button from '@ndla/button';
13
- import { debounce } from 'lodash';
13
+ import debounce from 'lodash/debounce';
14
14
  import { classes } from './filterClasses';
15
15
  import ToggleItem from './ToggleItem';
16
16
  import ActiveFilters from '../Search/ActiveFilters';
@@ -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/react';
13
- import { throttle } from 'lodash';
13
+ import throttle from 'lodash/throttle';
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';
@@ -8,7 +8,6 @@
8
8
  */
9
9
  import React from 'react';
10
10
  import { breakpoints, fonts, mq, colors, spacing } from '@ndla/core';
11
- import { useTranslation } from 'react-i18next';
12
11
  import { Launch } from '@ndla/icons/common';
13
12
  import { SafeLinkButton } from '@ndla/safelink';
14
13
  import styled from '@emotion/styled';
@@ -90,10 +89,10 @@ interface Props {
90
89
  title: string;
91
90
  caption: string;
92
91
  url: string;
92
+ buttonText: string;
93
93
  }
94
94
 
95
- export const ResourceBox = ({ image, title, caption, url }: Props) => {
96
- const { t } = useTranslation();
95
+ export const ResourceBox = ({ image, title, caption, url, buttonText }: Props) => {
97
96
  return (
98
97
  <ResourceBoxContainer>
99
98
  <StyledImage src={image.src} alt={image.alt} />
@@ -102,7 +101,7 @@ export const ResourceBox = ({ image, title, caption, url }: Props) => {
102
101
  <Caption>{caption}</Caption>
103
102
 
104
103
  <StyledButton to={url} target="_blank" outline borderShape="rounded">
105
- {t('license.other.itemImage.ariaLabel')}
104
+ {buttonText}
106
105
  <Launch aria-hidden />
107
106
  </StyledButton>
108
107
  </ContentWrapper>
@@ -12,7 +12,7 @@
12
12
  import React, { Fragment, useEffect, useState } from 'react';
13
13
  import PropTypes from 'prop-types';
14
14
  import BEMHelper from 'react-bem-helper';
15
- import { debounce } from 'lodash';
15
+ import debounce from 'lodash/debounce';
16
16
  import { spacing } from '@ndla/core';
17
17
  import styled from '@emotion/styled';
18
18
 
@@ -12,11 +12,11 @@ import Tooltip from '@ndla/tooltip';
12
12
  import styled from '@emotion/styled';
13
13
  import { ButtonV2 as Button } from '@ndla/button';
14
14
  import { Plus } from '@ndla/icons/action';
15
- import { FolderType } from './types';
15
+ import { IFolder } from '@ndla/types-learningpath-api';
16
16
 
17
17
  interface AddFolderButtonProps {
18
18
  canAddFolder: boolean;
19
- focusedFolder?: FolderType;
19
+ focusedFolder?: IFolder;
20
20
  setNewFolderParentId: (id?: string) => void;
21
21
  setShowTree: (value: boolean) => void;
22
22
  loading?: boolean;
@@ -11,9 +11,10 @@ import styled from '@emotion/styled';
11
11
  import { useForwardedRef } from '@ndla/util';
12
12
  import { breakpoints, colors, mq, spacing } from '@ndla/core';
13
13
  import { ChevronUp, ChevronDown } from '@ndla/icons/common';
14
+ import { IFolder } from '@ndla/types-learningpath-api';
14
15
  import { ButtonV2 as Button, IconButtonV2 as IconButton } from '@ndla/button';
15
16
  import { treestructureId } from './helperFunctions';
16
- import { FolderType, TreeStructureType } from './types';
17
+ import { TreeStructureType } from './types';
17
18
  import { arrowNavigation } from './arrowNavigation';
18
19
  import ContentLoader from '../ContentLoader';
19
20
 
@@ -52,15 +53,15 @@ interface Props {
52
53
  showTree: boolean;
53
54
  type: TreeStructureType;
54
55
  label?: string;
56
+ focusedFolder?: IFolder;
57
+ selectedFolder?: IFolder;
58
+ setSelectedFolder: (folder: IFolder) => void;
55
59
  loading?: boolean;
56
- focusedFolder?: FolderType;
57
- selectedFolder?: FolderType;
58
- setSelectedFolder: (folder: FolderType) => void;
59
60
  onToggleTree: (open: boolean) => void;
60
- flattenedFolders: FolderType[];
61
+ flattenedFolders: IFolder[];
61
62
  onOpenFolder: (id: string) => void;
62
63
  onCloseFolder: (id: string) => void;
63
- setFocusedFolder: (folder: FolderType) => void;
64
+ setFocusedFolder: (folder: IFolder) => void;
64
65
  ariaDescribedby?: string;
65
66
  }
66
67
 
@@ -14,7 +14,8 @@ import { Done } from '@ndla/icons/editor';
14
14
  import { ButtonV2 as Button } from '@ndla/button';
15
15
  import { colors, spacing, animations, spacingUnit, misc, fonts } from '@ndla/core';
16
16
  import SafeLink from '@ndla/safelink';
17
- import { CommonFolderItemsProps, FolderType } from './types';
17
+ import { IFolder } from '@ndla/types-learningpath-api';
18
+ import { CommonFolderItemsProps } from './types';
18
19
  import { arrowNavigation } from './arrowNavigation';
19
20
  import { treestructureId } from './helperFunctions';
20
21
 
@@ -104,8 +105,9 @@ const FolderNameLink = styled(SafeLink, { shouldForwardProp })<FolderNameProps>`
104
105
 
105
106
  interface Props extends CommonFolderItemsProps {
106
107
  isOpen: boolean;
107
- folder: FolderType;
108
+ folder: IFolder;
108
109
  isCreatingFolder?: boolean;
110
+ index: number;
109
111
  }
110
112
 
111
113
  const FolderItem = ({
@@ -125,9 +127,10 @@ const FolderItem = ({
125
127
  isCreatingFolder,
126
128
  type,
127
129
  closeTree,
130
+ index,
128
131
  }: Props) => {
129
132
  const { t } = useTranslation();
130
- const { id, name, isNavigation } = folder;
133
+ const { id, name } = folder;
131
134
  const ref = useRef<HTMLButtonElement & HTMLAnchorElement>(null);
132
135
  const selected = selectedFolder ? selectedFolder.id === id : false;
133
136
 
@@ -159,17 +162,17 @@ const FolderItem = ({
159
162
  }
160
163
  }, [focusedFolder, ref, id, isCreatingFolder, type]);
161
164
 
162
- const linkPath = `/minndla${!isNavigation ? '/folders' : ''}/${id}`;
165
+ const linkPath = `/minndla/folders/${id}`;
163
166
 
164
167
  const containsResource =
165
168
  targetResource && folder.resources.some((resource) => resource.resourceId === targetResource.resourceId);
166
169
 
167
170
  const emptyFolder = folder.subfolders.length === 0;
168
-
169
171
  const isMaxDepth = level > maxLevel;
170
-
171
172
  const hideArrow = isMaxDepth || emptyFolder;
172
173
 
174
+ const tabable = selected || focused || (!focusedFolder && !folder.parentId && index === 0);
175
+
173
176
  return type === 'navigation' ? (
174
177
  <FolderNameLink
175
178
  role="treeitem"
@@ -187,7 +190,7 @@ const FolderItem = ({
187
190
  arrowNavigation(e, id, visibleFolders, setFocusedFolder, onOpenFolder, onCloseFolder);
188
191
  }}
189
192
  to={loading ? '' : linkPath}
190
- tabIndex={selected || focused ? 0 : -1}
193
+ tabIndex={tabable ? 0 : -1}
191
194
  selected={selected}
192
195
  onFocus={() => setFocusedFolder(folder)}
193
196
  onClick={handleClickFolder}>
@@ -9,9 +9,9 @@
9
9
  import React, { ReactNode } from 'react';
10
10
  import styled from '@emotion/styled';
11
11
  import { animations } from '@ndla/core';
12
+ import { IFolder } from '@ndla/types-learningpath-api';
12
13
  import FolderItem from './FolderItem';
13
- import { CommonFolderItemsProps, FolderType, NewFolderInputFunc, OnCreatedFunc, TreeStructureType } from './types';
14
- import NavigationLink from './NavigationLink';
14
+ import { CommonFolderItemsProps, NewFolderInputFunc, OnCreatedFunc, TreeStructureType } from './types';
15
15
  import { treestructureId } from './helperFunctions';
16
16
 
17
17
  const StyledUL = styled.ul`
@@ -38,11 +38,11 @@ const StyledLI = styled.li<StyledLiProps>`
38
38
  `;
39
39
 
40
40
  export interface FolderItemsProps extends CommonFolderItemsProps {
41
- folders: FolderType[];
41
+ folders: IFolder[];
42
42
  newFolderParentId: string | undefined;
43
43
  onCancelNewFolder: () => void;
44
44
  openFolders: string[];
45
- parentFolder?: FolderType;
45
+ parentFolder?: IFolder;
46
46
  children?: ReactNode;
47
47
  onCreate: OnCreatedFunc;
48
48
  newFolderInput?: NewFolderInputFunc;
@@ -74,44 +74,39 @@ const FolderItems = ({
74
74
  aria-labelledby={level === 0 && type === 'picker' ? treestructureId(type, 'label') : undefined}
75
75
  role={level === 0 ? 'tree' : 'group'}>
76
76
  {children}
77
- {folders.map((folder) => {
77
+ {folders.map((folder, index) => {
78
78
  const { subfolders, id } = folder;
79
79
  const isOpen = openFolders?.includes(id);
80
80
 
81
81
  return (
82
82
  <StyledLI key={id} tabIndex={-1} role="none" type={type}>
83
- {folder.isNavigation ? (
84
- <NavigationLink folder={folder} isOpen={isOpen} level={level} type={type} loading={loading} {...rest} />
85
- ) : (
86
- <>
87
- <FolderItem
88
- folder={folder}
89
- isOpen={isOpen}
90
- level={level}
91
- loading={loading}
92
- type={type}
93
- isCreatingFolder={!!newFolderParentId}
94
- {...rest}
95
- />
96
- {((subfolders && isOpen) || newFolderParentId === id) && (
97
- <FolderItems
98
- parentFolder={folder}
99
- folders={subfolders}
100
- level={level + 1}
101
- loading={loading}
102
- type={type}
103
- newFolderParentId={newFolderParentId}
104
- onCancelNewFolder={onCancelNewFolder}
105
- openFolders={openFolders}
106
- newFolderInput={newFolderInput}
107
- onCreate={onCreate}
108
- {...rest}>
109
- {newFolderParentId === id && (
110
- <li role="none">{newFolderInput?.({ parentId: id, onClose: onCancelNewFolder, onCreate })}</li>
111
- )}
112
- </FolderItems>
83
+ <FolderItem
84
+ index={index}
85
+ folder={folder}
86
+ isOpen={isOpen}
87
+ level={level}
88
+ loading={loading}
89
+ type={type}
90
+ isCreatingFolder={!!newFolderParentId}
91
+ {...rest}
92
+ />
93
+ {((subfolders && isOpen) || newFolderParentId === id) && (
94
+ <FolderItems
95
+ parentFolder={folder}
96
+ folders={subfolders}
97
+ level={level + 1}
98
+ loading={loading}
99
+ type={type}
100
+ newFolderParentId={newFolderParentId}
101
+ onCancelNewFolder={onCancelNewFolder}
102
+ openFolders={openFolders}
103
+ newFolderInput={newFolderInput}
104
+ onCreate={onCreate}
105
+ {...rest}>
106
+ {newFolderParentId === id && (
107
+ <li role="none">{newFolderInput?.({ parentId: id, onClose: onCancelNewFolder, onCreate })}</li>
113
108
  )}
114
- </>
109
+ </FolderItems>
115
110
  )}
116
111
  </StyledLI>
117
112
  );
@@ -10,11 +10,11 @@ import React, { useEffect, useState, useMemo, useRef } from 'react';
10
10
  import styled from '@emotion/styled';
11
11
  import { colors, fonts, misc, utils } from '@ndla/core';
12
12
  import { css } from '@emotion/react';
13
- import { uniq } from 'lodash';
13
+ import uniq from 'lodash/uniq';
14
14
  import { IFolder } from '@ndla/types-learningpath-api';
15
15
  import FolderItems from './FolderItems';
16
16
  import { flattenFolders, treestructureId } from './helperFunctions';
17
- import { CommonTreeStructureProps, FolderType, NewFolderInputFunc, TreeStructureType } from './types';
17
+ import { CommonTreeStructureProps, NewFolderInputFunc, TreeStructureType } from './types';
18
18
  import ComboboxButton from './ComboboxButton';
19
19
  import AddFolderButton from './AddFolderButton';
20
20
 
@@ -69,7 +69,7 @@ const ScrollableDiv = styled.div<ScrollableDivProps>`
69
69
 
70
70
  export interface TreeStructureProps extends CommonTreeStructureProps {
71
71
  defaultOpenFolders?: string[];
72
- folders: FolderType[];
72
+ folders: IFolder[];
73
73
  label?: string;
74
74
  maxLevel?: number;
75
75
  newFolderInput?: NewFolderInputFunc;
@@ -96,8 +96,8 @@ const TreeStructure = ({
96
96
  const [openFolders, setOpenFolders] = useState<string[]>(defaultOpenFolders || []);
97
97
 
98
98
  const [newFolderParentId, setNewFolderParentId] = useState<string | undefined>();
99
- const [focusedFolder, _setFocusedFolder] = useState<FolderType | undefined>();
100
- const [selectedFolder, _setSelectedFolder] = useState<FolderType | undefined>();
99
+ const [focusedFolder, _setFocusedFolder] = useState<IFolder | undefined>();
100
+ const [selectedFolder, _setSelectedFolder] = useState<IFolder | undefined>();
101
101
  const [showTree, setShowTree] = useState(type === 'navigation');
102
102
 
103
103
  const flattenedFolders = useMemo(() => flattenFolders(folders, openFolders), [folders, openFolders]);
@@ -133,12 +133,12 @@ const TreeStructure = ({
133
133
  }
134
134
  };
135
135
 
136
- const setSelectedFolder = (folder: FolderType) => {
136
+ const setSelectedFolder = (folder: IFolder) => {
137
137
  _setSelectedFolder(folder);
138
138
  onSelectFolder?.(folder.id);
139
139
  };
140
140
 
141
- const setFocusedFolder = (folder: FolderType) => {
141
+ const setFocusedFolder = (folder: IFolder) => {
142
142
  _setFocusedFolder(folder);
143
143
  setNewFolderParentId(undefined);
144
144
 
@@ -6,13 +6,13 @@
6
6
  *
7
7
  */
8
8
 
9
+ import { IFolder } from '@ndla/types-learningpath-api';
9
10
  import { KeyboardEvent } from 'react';
10
- import { FolderType } from './types';
11
11
 
12
12
  const navigateVertical = (
13
- visibleFolders: FolderType[],
13
+ visibleFolders: IFolder[],
14
14
  folderId: string,
15
- setFocusedFolderId: (id: FolderType) => void,
15
+ setFocusedFolderId: (id: IFolder) => void,
16
16
  direction: 1 | -1,
17
17
  ) => {
18
18
  const currentIndex = visibleFolders.findIndex((folder) => folder.id === folderId);
@@ -27,8 +27,8 @@ const arrowKeys = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Enter'];
27
27
  export const arrowNavigation = (
28
28
  e: KeyboardEvent<HTMLElement>,
29
29
  id: string,
30
- visibleFolders: FolderType[],
31
- setFocusedFolderId: (id: FolderType) => void,
30
+ visibleFolders: IFolder[],
31
+ setFocusedFolderId: (id: IFolder) => void,
32
32
  onOpen: (id: string) => void,
33
33
  onClose: (id: string) => void,
34
34
  ) => {
@@ -1,12 +1,13 @@
1
- import { FolderType, TreeStructureType } from './types';
1
+ import { IFolder } from '@ndla/types-learningpath-api';
2
+ import { TreeStructureType } from './types';
2
3
 
3
- export const flattenFolders = (folders: FolderType[], openFolders?: string[]): FolderType[] => {
4
+ export const flattenFolders = (folders: IFolder[], openFolders?: string[]): IFolder[] => {
4
5
  return folders.reduce((acc, { subfolders, id, ...rest }) => {
5
6
  if (!subfolders || (openFolders && !openFolders.includes(id))) {
6
7
  return acc.concat({ subfolders, id, ...rest });
7
8
  }
8
9
  return acc.concat({ subfolders, id, ...rest }, flattenFolders(subfolders, openFolders));
9
- }, [] as FolderType[]);
10
+ }, [] as IFolder[]);
10
11
  };
11
12
 
12
13
  export const treestructureId = (type: TreeStructureType, modifier: string) => {
@@ -7,6 +7,5 @@
7
7
  */
8
8
 
9
9
  import TreeStructure from './TreeStructure';
10
- export type { FolderType } from './types';
11
10
  export type { TreeStructureProps } from './TreeStructure';
12
11
  export { TreeStructure };
@@ -9,11 +9,6 @@
9
9
  import { ReactNode } from 'react';
10
10
  import { IFolder, IResource } from '@ndla/types-learningpath-api';
11
11
 
12
- export interface FolderType extends IFolder {
13
- icon?: ReactNode;
14
- isNavigation?: boolean;
15
- }
16
-
17
12
  export type TreeStructureType = 'navigation' | 'picker';
18
13
 
19
14
  export type OnCreatedFunc = (folder: IFolder | undefined, parentId: string) => void;
@@ -35,14 +30,14 @@ export interface CommonTreeStructureProps {
35
30
  }
36
31
 
37
32
  export interface CommonFolderItemsProps extends CommonTreeStructureProps {
38
- focusedFolder?: FolderType;
33
+ focusedFolder?: IFolder;
39
34
  level: number;
40
35
  maxLevel: number;
41
- selectedFolder?: FolderType;
36
+ selectedFolder?: IFolder;
42
37
  onCloseFolder: (id: string) => void;
43
38
  onOpenFolder: (id: string) => void;
44
- setFocusedFolder: (folder: FolderType) => void;
45
- setSelectedFolder: (folder: FolderType) => void;
46
- visibleFolders: FolderType[];
39
+ setFocusedFolder: (folder: IFolder) => void;
40
+ setSelectedFolder: (folder: IFolder) => void;
41
+ visibleFolders: IFolder[];
47
42
  closeTree: () => void;
48
43
  }
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import { groupBy } from 'lodash';
8
+ import groupBy from 'lodash/groupBy';
9
9
  import { FeideGoGroup, FeideGrep, FeideGroup, FeideOrg, FeideUserApiType } from './apiTypes';
10
10
 
11
11
  type GoGroupType = 'basic' | 'teaching' | 'other';
package/src/index.ts CHANGED
@@ -251,7 +251,7 @@ export { SnackbarProvider, useSnack, BaseSnack, DefaultSnackbar } from './SnackB
251
251
  export type { Snack, SnackContext } from './SnackBar';
252
252
  export { InfoBlock } from './InfoBlock';
253
253
  export { TreeStructure } from './TreeStructure';
254
- export type { FolderType, TreeStructureProps } from './TreeStructure';
254
+ export type { TreeStructureProps } from './TreeStructure';
255
255
 
256
256
  export { SearchField, SearchResultList, SearchResultItem, ActiveFilters, ToggleSearchButton } from './Search';
257
257
  export { default as LetterFilter } from './LetterFilter';
@@ -1,44 +0,0 @@
1
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
5
- function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
6
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
8
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
9
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
10
- /**
11
- * Copyright (c) 2022-present, NDLA.
12
- *
13
- * This source code is licensed under the GPLv3 license found in the
14
- * LICENSE file in the root directory of this source tree.
15
- *
16
- */
17
-
18
- import { useArgs } from '@storybook/client-api';
19
- import React from 'react';
20
- import { defaultParameters } from '../../../designmanual/stories/defaults';
21
- import LetterFilter from './LetterFilter';
22
- import { jsx as _jsx } from "@emotion/react/jsx-runtime";
23
- export default {
24
- title: 'Enkle komponenter/LetterFilter',
25
- component: LetterFilter,
26
- parameters: _objectSpread({}, defaultParameters),
27
- args: {
28
- enabledLetters: ['a', 'c'],
29
- onChange: function onChange(value) {}
30
- }
31
- };
32
- export var LetterFilterStory = function LetterFilterStory(args) {
33
- var _useArgs = useArgs(),
34
- _useArgs2 = _slicedToArray(_useArgs, 2),
35
- updateArgs = _useArgs2[1];
36
- return _jsx(LetterFilter, _objectSpread(_objectSpread({}, args), {}, {
37
- onChange: function onChange(val) {
38
- return updateArgs({
39
- value: val
40
- });
41
- }
42
- }));
43
- };
44
- LetterFilterStory.storyName = 'LetterFilter';