@ndla/ui 34.6.6 → 35.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.
- package/es/Embed/BrightcoveEmbed.js +4 -2
- package/es/Embed/ExternalEmbed.js +3 -1
- package/es/Embed/H5pEmbed.js +9 -32
- package/es/Embed/IframeEmbed.js +2 -0
- package/es/Embed/conceptComponents.js +13 -11
- package/es/SearchTypeResult/SearchHeader.js +20 -14
- package/es/SearchTypeResult/SearchItem.js +39 -11
- package/lib/Embed/BrightcoveEmbed.js +4 -2
- package/lib/Embed/ExternalEmbed.js +3 -1
- package/lib/Embed/H5pEmbed.js +9 -32
- package/lib/Embed/IframeEmbed.js +2 -0
- package/lib/Embed/conceptComponents.js +13 -11
- package/lib/SearchTypeResult/SearchHeader.d.ts +2 -1
- package/lib/SearchTypeResult/SearchHeader.js +20 -14
- package/lib/SearchTypeResult/SearchItem.js +39 -19
- package/package.json +6 -6
- package/src/Embed/BrightcoveEmbed.tsx +2 -0
- package/src/Embed/ExternalEmbed.tsx +2 -0
- package/src/Embed/H5pEmbed.tsx +4 -27
- package/src/Embed/IframeEmbed.tsx +2 -0
- package/src/Embed/conceptComponents.tsx +2 -0
- package/src/SearchTypeResult/SearchHeader.tsx +12 -6
- package/src/SearchTypeResult/SearchItem.tsx +12 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ndla/ui",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "35.0.0",
|
|
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.15",
|
|
35
|
-
"@ndla/button": "^
|
|
35
|
+
"@ndla/button": "^10.0.0",
|
|
36
36
|
"@ndla/carousel": "^3.0.3",
|
|
37
37
|
"@ndla/core": "^3.1.2",
|
|
38
|
-
"@ndla/forms": "^4.2.
|
|
38
|
+
"@ndla/forms": "^4.2.8",
|
|
39
39
|
"@ndla/hooks": "^2.0.2",
|
|
40
40
|
"@ndla/icons": "^2.2.3",
|
|
41
41
|
"@ndla/licenses": "^7.0.1",
|
|
42
42
|
"@ndla/modal": "^2.2.7",
|
|
43
|
-
"@ndla/notion": "^4.2.
|
|
44
|
-
"@ndla/safelink": "^4.0.
|
|
43
|
+
"@ndla/notion": "^4.2.5",
|
|
44
|
+
"@ndla/safelink": "^4.0.10",
|
|
45
45
|
"@ndla/switch": "^1.0.7",
|
|
46
46
|
"@ndla/tabs": "^2.1.8",
|
|
47
47
|
"@ndla/tooltip": "^4.0.10",
|
|
@@ -87,5 +87,5 @@
|
|
|
87
87
|
"publishConfig": {
|
|
88
88
|
"access": "public"
|
|
89
89
|
},
|
|
90
|
-
"gitHead": "
|
|
90
|
+
"gitHead": "908efc9af085f4cd4ef3533250956ab2c66cb570"
|
|
91
91
|
}
|
|
@@ -69,6 +69,8 @@ const BrightcoveEmbed = ({ embed, isConcept }: Props) => {
|
|
|
69
69
|
if (iframe) {
|
|
70
70
|
const [width, height] = [parseInt(iframe.width), parseInt(iframe.height)];
|
|
71
71
|
iframe.style.aspectRatio = `${width}/${height}`;
|
|
72
|
+
iframe.width = '';
|
|
73
|
+
iframe.height = '';
|
|
72
74
|
}
|
|
73
75
|
}, []);
|
|
74
76
|
if (embed.status === 'error') {
|
|
@@ -34,6 +34,8 @@ const ExternalEmbed = ({ embed, isConcept }: Props) => {
|
|
|
34
34
|
if (iframe) {
|
|
35
35
|
const [width, height] = [parseInt(iframe.width), parseInt(iframe.height)];
|
|
36
36
|
iframe.style.aspectRatio = `${width ? width : 16}/${height ? height : 9}`;
|
|
37
|
+
iframe.width = '';
|
|
38
|
+
iframe.height = '';
|
|
37
39
|
}
|
|
38
40
|
}, []);
|
|
39
41
|
if (embed.status === 'error') {
|
package/src/Embed/H5pEmbed.tsx
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import styled from '@emotion/styled';
|
|
10
10
|
import { H5pMetaData } from '@ndla/types-embed';
|
|
11
|
-
import
|
|
11
|
+
import React from 'react';
|
|
12
12
|
import { useTranslation } from 'react-i18next';
|
|
13
13
|
import { errorSvgSrc } from './ImageEmbed';
|
|
14
14
|
|
|
@@ -26,18 +26,6 @@ const StyledFigure = styled.figure`
|
|
|
26
26
|
const H5pEmbed = ({ embed, isConcept }: Props) => {
|
|
27
27
|
const { t } = useTranslation();
|
|
28
28
|
|
|
29
|
-
const iframeRef = useRef<HTMLIFrameElement>(null);
|
|
30
|
-
const figRef = useRef<HTMLElement>(null);
|
|
31
|
-
|
|
32
|
-
useEffect(() => {
|
|
33
|
-
const iframe =
|
|
34
|
-
embed.status === 'success' && embed.data.oembed ? figRef.current?.querySelector('iframe') : iframeRef.current;
|
|
35
|
-
if (iframe) {
|
|
36
|
-
const [width, height] = [parseInt(iframe.width), parseInt(iframe.height)];
|
|
37
|
-
iframe.style.aspectRatio = `${width ? width : 16}/${height ? height : 9}`;
|
|
38
|
-
}
|
|
39
|
-
}, [embed]);
|
|
40
|
-
|
|
41
29
|
if (embed.status === 'error') {
|
|
42
30
|
return (
|
|
43
31
|
<figure className={isConcept ? '' : 'c-figure'}>
|
|
@@ -50,23 +38,12 @@ const H5pEmbed = ({ embed, isConcept }: Props) => {
|
|
|
50
38
|
const classes = `c-figure ${fullColumnClass} c-figure--resize`;
|
|
51
39
|
|
|
52
40
|
if (embed.data.oembed) {
|
|
53
|
-
return
|
|
54
|
-
<StyledFigure
|
|
55
|
-
className={classes}
|
|
56
|
-
ref={figRef}
|
|
57
|
-
//@ts-ignore
|
|
58
|
-
// eslint-disable-next-line react/no-unknown-property
|
|
59
|
-
resizeiframe="true"
|
|
60
|
-
dangerouslySetInnerHTML={{ __html: embed.data.oembed.html ?? '' }}
|
|
61
|
-
/>
|
|
62
|
-
);
|
|
41
|
+
return <StyledFigure className={classes} dangerouslySetInnerHTML={{ __html: embed.data.oembed.html ?? '' }} />;
|
|
63
42
|
}
|
|
64
43
|
|
|
65
44
|
return (
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
<StyledFigure className={classes} resizeiframe="true">
|
|
69
|
-
<iframe title={embed.embedData.url} ref={iframeRef} aria-label={embed.embedData.url} src={embed.embedData.url} />
|
|
45
|
+
<StyledFigure className={classes}>
|
|
46
|
+
<iframe title={embed.embedData.url} aria-label={embed.embedData.url} src={embed.embedData.url} />
|
|
70
47
|
</StyledFigure>
|
|
71
48
|
);
|
|
72
49
|
};
|
|
@@ -29,6 +29,8 @@ const ExternalEmbed = ({ embed, isConcept }: Props) => {
|
|
|
29
29
|
if (iframe) {
|
|
30
30
|
const [width, height] = [parseInt(iframe.width), parseInt(iframe.height)];
|
|
31
31
|
iframe.style.aspectRatio = `${width ? width : 16}/${height ? height : 9}`;
|
|
32
|
+
iframe.width = '';
|
|
33
|
+
iframe.height = '';
|
|
32
34
|
}
|
|
33
35
|
}, []);
|
|
34
36
|
|
|
@@ -255,6 +255,8 @@ export const ConceptNotionV2 = forwardRef<HTMLDivElement, ConceptNotionProps>(
|
|
|
255
255
|
if (iframe) {
|
|
256
256
|
const [width, height] = [parseInt(iframe.width), parseInt(iframe.height)];
|
|
257
257
|
iframe.style.aspectRatio = `${width ? width : 16}/${height ? height : 9}`;
|
|
258
|
+
iframe.width = '';
|
|
259
|
+
iframe.height = '';
|
|
258
260
|
}
|
|
259
261
|
}, []);
|
|
260
262
|
|
|
@@ -10,6 +10,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
10
10
|
import styled from '@emotion/styled';
|
|
11
11
|
import { breakpoints, fonts, mq, spacing } from '@ndla/core';
|
|
12
12
|
import { ButtonV2 } from '@ndla/button';
|
|
13
|
+
import { Spinner } from '@ndla/icons';
|
|
13
14
|
|
|
14
15
|
import SearchFieldHeader from './SearchFieldHeader';
|
|
15
16
|
import { CompetenceGoalsItemType } from '../types';
|
|
@@ -71,6 +72,7 @@ type Props = {
|
|
|
71
72
|
onSearchValueChange: (value: string) => void;
|
|
72
73
|
onSubmit: (event: FormEvent<HTMLFormElement>) => void;
|
|
73
74
|
noResults?: boolean;
|
|
75
|
+
loading: boolean;
|
|
74
76
|
};
|
|
75
77
|
|
|
76
78
|
const SearchHeader = ({
|
|
@@ -84,6 +86,7 @@ const SearchHeader = ({
|
|
|
84
86
|
filters,
|
|
85
87
|
competenceGoals,
|
|
86
88
|
noResults,
|
|
89
|
+
loading,
|
|
87
90
|
}: Props) => {
|
|
88
91
|
const { t } = useTranslation();
|
|
89
92
|
const [isNarrowScreen, setIsNarrowScreen] = useState<boolean | undefined>();
|
|
@@ -122,12 +125,15 @@ const SearchHeader = ({
|
|
|
122
125
|
/>
|
|
123
126
|
</SearchInputWrapper>
|
|
124
127
|
<PhraseWrapper>
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
128
|
+
<div aria-live="assertive">
|
|
129
|
+
{!loading && searchPhrase && (
|
|
130
|
+
<>
|
|
131
|
+
<PhraseText>{phraseText}</PhraseText>
|
|
132
|
+
<PhraseText>{removeFilterSuggestion}</PhraseText>
|
|
133
|
+
</>
|
|
134
|
+
)}
|
|
135
|
+
{loading && <div aria-label={t('loading')} />}
|
|
136
|
+
</div>
|
|
131
137
|
{searchPhraseSuggestion && (
|
|
132
138
|
<PhraseSuggestionText>
|
|
133
139
|
{t('searchPage.resultType.searchPhraseSuggestion')}{' '}
|
|
@@ -43,6 +43,12 @@ const Container = styled.article`
|
|
|
43
43
|
}
|
|
44
44
|
`;
|
|
45
45
|
|
|
46
|
+
const ButtonWrapper = styled.div`
|
|
47
|
+
z-index: 1;
|
|
48
|
+
display: flex;
|
|
49
|
+
flex-direction: column;
|
|
50
|
+
`;
|
|
51
|
+
|
|
46
52
|
const ItemTitle = styled.h3<ItemTypeProps>`
|
|
47
53
|
display: inline;
|
|
48
54
|
${fonts.sizes('24px', '28px')};
|
|
@@ -87,6 +93,10 @@ const ContentWrapper = styled.main`
|
|
|
87
93
|
padding: ${spacing.small} ${spacing.normal};
|
|
88
94
|
`;
|
|
89
95
|
|
|
96
|
+
const ButtonContainer = styled.div`
|
|
97
|
+
z-index: 1;
|
|
98
|
+
`;
|
|
99
|
+
|
|
90
100
|
export interface SearchItemProps {
|
|
91
101
|
id: string | number;
|
|
92
102
|
title: string;
|
|
@@ -105,7 +115,7 @@ export interface SearchItemType {
|
|
|
105
115
|
}
|
|
106
116
|
|
|
107
117
|
const SearchItem = ({ item, type }: SearchItemType) => {
|
|
108
|
-
const { title, url, ingress, contexts = [], img = null, labels = [] } = item;
|
|
118
|
+
const { title, url, ingress, contexts = [], img = null, labels = [], children } = item;
|
|
109
119
|
const linkRef = useRef<HTMLAnchorElement>(null);
|
|
110
120
|
|
|
111
121
|
const isTopic = type === contentTypes.TOPIC || type === contentTypes.MULTIDISCIPLINARY_TOPIC;
|
|
@@ -130,6 +140,7 @@ const SearchItem = ({ item, type }: SearchItemType) => {
|
|
|
130
140
|
<ItemText isTopic={isTopic}>{parse(ingress)}</ItemText>
|
|
131
141
|
{contexts.length > 0 && <ItemContexts contexts={contexts} id={item.id} title={item.title} />}
|
|
132
142
|
</ContentWrapper>
|
|
143
|
+
<ButtonWrapper>{children}</ButtonWrapper>
|
|
133
144
|
</Container>
|
|
134
145
|
);
|
|
135
146
|
};
|