@ndla/ui 43.0.3 → 44.0.1
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/Article/Article.js +6 -14
- package/es/Article/ArticleNotions.js +24 -48
- package/es/Article/index.js +1 -2
- package/es/ContactBlock/ContactBlock.js +13 -13
- package/es/Embed/ImageEmbed.js +2 -2
- package/es/Grid/Grid.js +15 -2
- package/es/Grid/index.js +1 -1
- package/es/LinkBlock/LinkBlock.js +16 -6
- package/es/{Article/ArticleContent.js → LinkBlock/LinkBlockSection.js} +22 -30
- package/es/LinkBlock/index.js +2 -1
- package/es/Topic/Topic.js +60 -42
- package/es/index.js +4 -3
- package/lib/Article/Article.d.ts +3 -9
- package/lib/Article/Article.js +6 -14
- package/lib/Article/ArticleNotions.d.ts +3 -9
- package/lib/Article/ArticleNotions.js +30 -56
- package/lib/Article/index.d.ts +1 -2
- package/lib/Article/index.js +0 -7
- package/lib/ContactBlock/ContactBlock.js +13 -13
- package/lib/Embed/ImageEmbed.d.ts +11 -1
- package/lib/Embed/ImageEmbed.js +3 -1
- package/lib/Grid/Grid.d.ts +4 -0
- package/lib/Grid/Grid.js +23 -10
- package/lib/Grid/index.d.ts +1 -1
- package/lib/Grid/index.js +10 -2
- package/lib/LinkBlock/LinkBlock.d.ts +2 -7
- package/lib/LinkBlock/LinkBlock.js +16 -6
- package/lib/LinkBlock/LinkBlockSection.d.ts +13 -0
- package/lib/{Article/ArticleContent.js → LinkBlock/LinkBlockSection.js} +22 -27
- package/lib/LinkBlock/index.d.ts +1 -0
- package/lib/LinkBlock/index.js +7 -0
- package/lib/Topic/Topic.d.ts +10 -17
- package/lib/Topic/Topic.js +62 -44
- package/lib/index.d.ts +3 -2
- package/lib/index.js +19 -6
- package/lib/types.d.ts +1 -1
- package/package.json +6 -5
- package/src/Article/Article.tsx +6 -16
- package/src/Article/ArticleNotions.tsx +9 -78
- package/src/Article/index.ts +1 -10
- package/src/ContactBlock/ContactBlock.tsx +3 -0
- package/src/Embed/ImageEmbed.tsx +2 -2
- package/src/Grid/Grid.tsx +9 -1
- package/src/Grid/index.ts +1 -1
- package/src/LinkBlock/LinkBlock.stories.tsx +18 -8
- package/src/LinkBlock/LinkBlock.tsx +12 -9
- package/src/LinkBlock/LinkBlockSection.tsx +42 -0
- package/src/LinkBlock/index.ts +1 -0
- package/src/Topic/Topic.tsx +58 -39
- package/src/index.ts +3 -2
- package/src/types.ts +1 -1
- package/lib/Article/ArticleContent.d.ts +0 -7
- package/src/Article/ArticleContent.tsx +0 -40
package/src/Topic/Topic.tsx
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { ReactNode, MouseEvent,
|
|
9
|
+
import { ReactNode, MouseEvent, useMemo } from 'react';
|
|
10
10
|
import styled from '@emotion/styled';
|
|
11
11
|
import { animations, breakpoints, colors, fonts, mq, spacing } from '@ndla/core';
|
|
12
12
|
|
|
@@ -17,12 +17,14 @@ import { ButtonV2 } from '@ndla/button';
|
|
|
17
17
|
import { CursorClick, ExpandTwoArrows } from '@ndla/icons/action';
|
|
18
18
|
import { css } from '@emotion/react';
|
|
19
19
|
import { useTranslation } from 'react-i18next';
|
|
20
|
+
import { EmbedMetaData } from '@ndla/types-embed';
|
|
20
21
|
import Loader from './Loader';
|
|
21
22
|
import { ItemProps } from '../Navigation/NavigationBox';
|
|
22
23
|
import { NavigationBox } from '../Navigation';
|
|
23
24
|
import { makeSrcQueryString, ImageCrop, ImageFocalPoint } from '../Image';
|
|
24
25
|
import { MessageBox } from '../Messages';
|
|
25
26
|
import { Heading } from '../Typography';
|
|
27
|
+
import { getCrop, getFocalPoint } from '../Embed/ImageEmbed';
|
|
26
28
|
|
|
27
29
|
type InvertItProps = {
|
|
28
30
|
invertedStyle?: boolean;
|
|
@@ -71,6 +73,7 @@ const ShowVisualElementWrapper = styled.div`
|
|
|
71
73
|
height: 100%;
|
|
72
74
|
overflow: hidden;
|
|
73
75
|
aspect-ratio: 1;
|
|
76
|
+
mask-image: radial-gradient(white, black);
|
|
74
77
|
-webkit-mask-image: -webkit-radial-gradient(white, black); /* Safari fix */
|
|
75
78
|
`;
|
|
76
79
|
|
|
@@ -187,31 +190,16 @@ const StyledModalHeader = styled(ModalHeader)`
|
|
|
187
190
|
padding: ${spacing.small} ${spacing.nsmall};
|
|
188
191
|
`;
|
|
189
192
|
|
|
190
|
-
const icons: Record<VisualElementProps['type'], ComponentType> = {
|
|
191
|
-
image: ExpandTwoArrows,
|
|
192
|
-
video: PlayCircleFilled,
|
|
193
|
-
other: CursorClick,
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
type VisualElementProps = {
|
|
197
|
-
type: 'image' | 'video' | 'other';
|
|
198
|
-
element: ReactNode;
|
|
199
|
-
};
|
|
200
|
-
|
|
201
193
|
export type TopicProps = {
|
|
202
194
|
id?: string;
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
image?: {
|
|
207
|
-
url: string;
|
|
208
|
-
alt: string;
|
|
209
|
-
crop?: ImageCrop;
|
|
210
|
-
focalPoint?: ImageFocalPoint;
|
|
211
|
-
};
|
|
212
|
-
visualElement?: VisualElementProps;
|
|
213
|
-
resources?: ReactNode;
|
|
195
|
+
metaImage?: {
|
|
196
|
+
url: string;
|
|
197
|
+
alt: string;
|
|
214
198
|
};
|
|
199
|
+
title: string;
|
|
200
|
+
introduction: string;
|
|
201
|
+
resources?: ReactNode;
|
|
202
|
+
visualElementEmbedMeta?: EmbedMetaData;
|
|
215
203
|
subTopics?: ItemProps[] | null | undefined;
|
|
216
204
|
onSubTopicSelected?: (event: MouseEvent<HTMLElement>, id?: string) => void;
|
|
217
205
|
isLoading?: boolean;
|
|
@@ -223,11 +211,21 @@ export type TopicProps = {
|
|
|
223
211
|
frame?: boolean;
|
|
224
212
|
messageBox?: string;
|
|
225
213
|
children?: ReactNode;
|
|
214
|
+
visualElement?: ReactNode;
|
|
226
215
|
};
|
|
227
216
|
|
|
217
|
+
interface MetaImageType {
|
|
218
|
+
url: string;
|
|
219
|
+
alt: string;
|
|
220
|
+
crop?: ImageCrop;
|
|
221
|
+
focalPoint?: ImageFocalPoint;
|
|
222
|
+
}
|
|
223
|
+
|
|
228
224
|
const Topic = ({
|
|
229
225
|
id,
|
|
230
|
-
|
|
226
|
+
title,
|
|
227
|
+
introduction,
|
|
228
|
+
resources,
|
|
231
229
|
subTopics,
|
|
232
230
|
onSubTopicSelected,
|
|
233
231
|
isLoading,
|
|
@@ -235,17 +233,40 @@ const Topic = ({
|
|
|
235
233
|
invertedStyle,
|
|
236
234
|
onToggleShowContent,
|
|
237
235
|
showContent,
|
|
236
|
+
metaImage: articleMetaImage,
|
|
238
237
|
isAdditionalTopic,
|
|
239
238
|
frame,
|
|
240
239
|
messageBox,
|
|
240
|
+
visualElementEmbedMeta,
|
|
241
241
|
children,
|
|
242
|
+
visualElement,
|
|
242
243
|
}: TopicProps) => {
|
|
243
244
|
const { t } = useTranslation();
|
|
244
245
|
const contentId = `expanded-description-${id}`;
|
|
245
246
|
const testId = 'nav-topic-about';
|
|
246
|
-
|
|
247
|
+
|
|
248
|
+
const VisualElementIcon = useMemo(() => {
|
|
249
|
+
if (!visualElementEmbedMeta || visualElementEmbedMeta.status === 'error') return null;
|
|
250
|
+
else if (visualElementEmbedMeta.resource === 'brightcove') {
|
|
251
|
+
return PlayCircleFilled;
|
|
252
|
+
} else if (visualElementEmbedMeta.resource === 'image') {
|
|
253
|
+
return ExpandTwoArrows;
|
|
254
|
+
} else return CursorClick;
|
|
255
|
+
}, [visualElementEmbedMeta]);
|
|
256
|
+
|
|
257
|
+
const metaImage: MetaImageType | undefined = useMemo(() => {
|
|
258
|
+
if (visualElementEmbedMeta?.resource === 'image' && visualElementEmbedMeta.status === 'success') {
|
|
259
|
+
return {
|
|
260
|
+
url: visualElementEmbedMeta.data.image?.imageUrl,
|
|
261
|
+
alt: visualElementEmbedMeta.data.alttext?.alttext,
|
|
262
|
+
crop: getCrop(visualElementEmbedMeta.embedData),
|
|
263
|
+
focalPoint: getFocalPoint(visualElementEmbedMeta.embedData),
|
|
264
|
+
};
|
|
265
|
+
} else return articleMetaImage;
|
|
266
|
+
}, [articleMetaImage, visualElementEmbedMeta]);
|
|
267
|
+
|
|
247
268
|
const wrapperStyle = [frame ? frameStyle : undefined, invertedStyle ? _invertedStyle : undefined];
|
|
248
|
-
if (isLoading
|
|
269
|
+
if (isLoading) {
|
|
249
270
|
return (
|
|
250
271
|
<Wrapper css={wrapperStyle} data-testid={testId}>
|
|
251
272
|
{isLoading ? <Loader /> : null}
|
|
@@ -259,7 +280,7 @@ const Topic = ({
|
|
|
259
280
|
<div>
|
|
260
281
|
<HeadingWrapper>
|
|
261
282
|
<Heading element="h1" headingStyle="h2" id={id} tabIndex={-1}>
|
|
262
|
-
{
|
|
283
|
+
{title}
|
|
263
284
|
</Heading>
|
|
264
285
|
{isAdditionalTopic && (
|
|
265
286
|
<>
|
|
@@ -268,23 +289,21 @@ const Topic = ({
|
|
|
268
289
|
</>
|
|
269
290
|
)}
|
|
270
291
|
</HeadingWrapper>
|
|
271
|
-
<TopicIntroduction>
|
|
272
|
-
{renderMarkdown ? parse(renderMarkdown(topic.introduction)) : topic.introduction}
|
|
273
|
-
</TopicIntroduction>
|
|
292
|
+
<TopicIntroduction>{renderMarkdown ? parse(renderMarkdown(introduction)) : introduction}</TopicIntroduction>
|
|
274
293
|
</div>
|
|
275
|
-
{
|
|
294
|
+
{metaImage && (
|
|
276
295
|
<TopicHeaderVisualElementWrapper>
|
|
277
|
-
{
|
|
296
|
+
{visualElementEmbedMeta?.status === 'success' ? (
|
|
278
297
|
<Modal>
|
|
279
298
|
<ModalTrigger>
|
|
280
299
|
<VisualElementButton
|
|
281
300
|
variant="stripped"
|
|
282
|
-
title={
|
|
301
|
+
title={visualElementEmbedMeta.resource === 'image' ? t('image.largeSize') : t('visualElement.show')}
|
|
283
302
|
>
|
|
284
303
|
<ShowVisualElementWrapper>
|
|
285
304
|
<TopicHeaderImage
|
|
286
|
-
src={`${
|
|
287
|
-
alt={
|
|
305
|
+
src={`${metaImage.url}?${makeSrcQueryString(800, metaImage.crop, metaImage.focalPoint)}`}
|
|
306
|
+
alt={metaImage.alt}
|
|
288
307
|
/>
|
|
289
308
|
<TopicHeaderOverlay />
|
|
290
309
|
</ShowVisualElementWrapper>
|
|
@@ -300,13 +319,13 @@ const Topic = ({
|
|
|
300
319
|
<StyledModalHeader>
|
|
301
320
|
<ModalCloseButton />
|
|
302
321
|
</StyledModalHeader>
|
|
303
|
-
{
|
|
322
|
+
{visualElement}
|
|
304
323
|
</ModalContent>
|
|
305
324
|
</Modal>
|
|
306
325
|
) : (
|
|
307
326
|
<TopicHeaderImage
|
|
308
|
-
src={`${
|
|
309
|
-
alt={
|
|
327
|
+
src={`${metaImage.url}?${makeSrcQueryString(400, metaImage.crop, metaImage.focalPoint)}`}
|
|
328
|
+
alt={metaImage.alt}
|
|
310
329
|
/>
|
|
311
330
|
)}
|
|
312
331
|
</TopicHeaderVisualElementWrapper>
|
|
@@ -349,7 +368,7 @@ const Topic = ({
|
|
|
349
368
|
invertedStyle={invertedStyle}
|
|
350
369
|
/>
|
|
351
370
|
)}
|
|
352
|
-
{
|
|
371
|
+
{resources}
|
|
353
372
|
</Wrapper>
|
|
354
373
|
);
|
|
355
374
|
};
|
package/src/index.ts
CHANGED
|
@@ -28,7 +28,6 @@ export {
|
|
|
28
28
|
|
|
29
29
|
export {
|
|
30
30
|
ArticleByline,
|
|
31
|
-
ArticleContent,
|
|
32
31
|
ArticleFootNotes,
|
|
33
32
|
ArticleIntroduction,
|
|
34
33
|
ArticleTitle,
|
|
@@ -264,7 +263,7 @@ export { KeyFigure } from './KeyFigure';
|
|
|
264
263
|
export { default as ContactBlock } from './ContactBlock';
|
|
265
264
|
export type { HeartButtonType } from './Embed';
|
|
266
265
|
export { CampaignBlock } from './CampaignBlock';
|
|
267
|
-
export { Grid } from './Grid';
|
|
266
|
+
export { Grid, GridParallaxItem } from './Grid';
|
|
268
267
|
export type { GridType } from './Grid';
|
|
269
268
|
export { Heading } from './Typography';
|
|
270
269
|
export type { HeadingLevel } from './types';
|
|
@@ -274,3 +273,5 @@ export { DefinitionTerm, DefinitionDescription } from './DefinitionList';
|
|
|
274
273
|
export type { ProgrammeV2 } from './ProgrammeCard';
|
|
275
274
|
|
|
276
275
|
export { Gloss } from './Gloss';
|
|
276
|
+
|
|
277
|
+
export { LinkBlock, LinkBlockSection } from './LinkBlock';
|
package/src/types.ts
CHANGED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2016-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 { useEffect } from 'react';
|
|
10
|
-
import {
|
|
11
|
-
initArticleScripts,
|
|
12
|
-
removeEventListenerForResize,
|
|
13
|
-
// @ts-ignore
|
|
14
|
-
} from '@ndla/article-scripts';
|
|
15
|
-
import { initPopovers, initTooltips } from '@ndla/tooltip';
|
|
16
|
-
import { initAudioPlayers } from '../AudioPlayer';
|
|
17
|
-
import { initCopyParagraphButtons } from '../CopyParagraphButton';
|
|
18
|
-
import { Locale } from '../types';
|
|
19
|
-
|
|
20
|
-
type Props = {
|
|
21
|
-
content: string;
|
|
22
|
-
locale: Locale;
|
|
23
|
-
};
|
|
24
|
-
const ArticleContent = ({ content, locale, ...rest }: Props) => {
|
|
25
|
-
useEffect(() => {
|
|
26
|
-
removeEventListenerForResize();
|
|
27
|
-
initArticleScripts();
|
|
28
|
-
initAudioPlayers(locale);
|
|
29
|
-
initTooltips();
|
|
30
|
-
initPopovers();
|
|
31
|
-
initCopyParagraphButtons();
|
|
32
|
-
return () => {
|
|
33
|
-
removeEventListenerForResize();
|
|
34
|
-
};
|
|
35
|
-
}, [content, locale]);
|
|
36
|
-
|
|
37
|
-
return <div dangerouslySetInnerHTML={{ __html: content }} {...rest} />;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export default ArticleContent;
|