@ndla/ui 8.2.3 → 9.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/Article/ArticleNotions.js +9 -7
- package/es/Figure/Figure.js +6 -5
- package/es/Figure/FigureExpandButton.js +6 -6
- package/es/Figure/FigureOpenDialogButton.js +45 -0
- package/es/Figure/index.js +2 -1
- package/es/Image/Image.js +1 -1
- package/es/MessageBox/MessageBox.js +8 -8
- package/es/Notion/ConceptNotion.js +79 -28
- package/es/Notion/FigureNotion.js +5 -6
- package/es/Notion/Notion.js +19 -98
- package/es/Notion/NotionImage.js +25 -6
- package/es/Notion/NotionVisualElement.js +49 -10
- package/es/ResourceBox/ResourceBox.js +34 -67
- package/es/Topic/Topic.js +21 -21
- package/es/all.css +1 -1
- package/es/index.js +1 -2
- package/es/locale/messages-en.js +6 -4
- package/es/locale/messages-nb.js +6 -4
- package/es/locale/messages-nn.js +6 -4
- package/es/locale/messages-se.js +5 -3
- package/es/locale/messages-sma.js +5 -3
- package/es/{CloseButton/index.js → model/SubjectTypes.js} +3 -4
- package/es/model/index.js +3 -1
- package/lib/Article/ArticleNotions.d.ts +2 -1
- package/lib/Article/ArticleNotions.js +9 -7
- package/lib/Figure/Figure.d.ts +2 -1
- package/lib/Figure/Figure.js +6 -5
- package/lib/Figure/FigureExpandButton.js +6 -6
- package/lib/Figure/FigureOpenDialogButton.d.ts +16 -0
- package/lib/Figure/FigureOpenDialogButton.js +57 -0
- package/lib/Figure/index.d.ts +1 -0
- package/lib/Figure/index.js +8 -0
- package/lib/Image/Image.js +1 -1
- package/lib/MessageBox/MessageBox.js +9 -9
- package/lib/Notion/ConceptNotion.d.ts +6 -7
- package/lib/Notion/ConceptNotion.js +84 -30
- package/lib/Notion/FigureNotion.d.ts +3 -2
- package/lib/Notion/FigureNotion.js +5 -7
- package/lib/Notion/Notion.d.ts +1 -12
- package/lib/Notion/Notion.js +23 -105
- package/lib/Notion/NotionImage.d.ts +2 -1
- package/lib/Notion/NotionImage.js +25 -7
- package/lib/Notion/NotionVisualElement.d.ts +6 -7
- package/lib/Notion/NotionVisualElement.js +48 -18
- package/lib/ResourceBox/ResourceBox.js +34 -63
- package/lib/Topic/Topic.js +21 -21
- package/lib/all.css +1 -1
- package/lib/index.d.ts +1 -2
- package/lib/index.js +7 -9
- package/lib/locale/messages-en.d.ts +5 -1
- package/lib/locale/messages-en.js +7 -4
- package/lib/locale/messages-nb.d.ts +5 -1
- package/lib/locale/messages-nb.js +7 -4
- package/lib/locale/messages-nn.d.ts +5 -1
- package/lib/locale/messages-nn.js +7 -4
- package/lib/locale/messages-se.d.ts +5 -1
- package/lib/locale/messages-se.js +6 -3
- package/lib/locale/messages-sma.d.ts +5 -1
- package/lib/locale/messages-sma.js +6 -3
- package/lib/{CloseButton/CloseButton.d.ts → model/SubjectTypes.d.ts} +2 -3
- package/lib/model/SubjectTypes.js +18 -0
- package/lib/model/index.d.ts +2 -0
- package/lib/model/index.js +4 -1
- package/package.json +9 -9
- package/src/Article/ArticleNotions.tsx +3 -2
- package/src/Figure/Figure.tsx +49 -41
- package/src/Figure/FigureExpandButton.tsx +4 -4
- package/src/Figure/FigureOpenDialogButton.tsx +37 -0
- package/src/Figure/component.figure.scss +4 -0
- package/src/Figure/index.ts +1 -0
- package/src/Image/Image.tsx +1 -1
- package/src/MessageBox/MessageBox.tsx +1 -1
- package/src/Notion/ConceptNotion.tsx +136 -37
- package/src/Notion/FigureNotion.tsx +6 -6
- package/src/Notion/Notion.tsx +7 -145
- package/src/Notion/NotionImage.tsx +44 -15
- package/src/Notion/NotionVisualElement.tsx +35 -8
- package/src/ResourceBox/ResourceBox.tsx +47 -102
- package/src/Topic/Topic.tsx +1 -1
- package/src/index.ts +2 -2
- package/src/locale/messages-en.ts +6 -2
- package/src/locale/messages-nb.ts +6 -2
- package/src/locale/messages-nn.ts +6 -2
- package/src/locale/messages-se.ts +5 -1
- package/src/locale/messages-sma.ts +5 -1
- package/{lib/CloseButton/index.d.ts → src/model/SubjectTypes.ts} +4 -4
- package/src/model/index.ts +2 -0
- package/es/CloseButton/CloseButton.js +0 -46
- package/lib/CloseButton/CloseButton.js +0 -54
- package/lib/CloseButton/index.js +0 -26
- package/src/CloseButton/CloseButton.tsx +0 -36
- package/src/CloseButton/index.ts +0 -13
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2012-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 from 'react';
|
|
10
|
+
import { Play } from '@ndla/icons/common';
|
|
11
|
+
import { ExpandTwoArrows } from '@ndla/icons/action';
|
|
12
|
+
import { CursorClick } from '@ndla/icons/action';
|
|
13
|
+
|
|
14
|
+
interface Props {
|
|
15
|
+
type?: 'image' | 'video' | 'h5p' | 'iframe' | 'external';
|
|
16
|
+
messages: {
|
|
17
|
+
zoomImageButtonLabel: string;
|
|
18
|
+
zoomOutImageButtonLabel: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function FigureOpenDialogButton({ messages, type }: Props) {
|
|
23
|
+
return (
|
|
24
|
+
<button
|
|
25
|
+
className="c-figure__fullscreen-btn"
|
|
26
|
+
type="button"
|
|
27
|
+
data-aria={messages.zoomImageButtonLabel}
|
|
28
|
+
data-ariaexpanded={messages.zoomOutImageButtonLabel}
|
|
29
|
+
aria-label={messages.zoomImageButtonLabel}>
|
|
30
|
+
{type === 'image' && <ExpandTwoArrows className="contracted-icon" />}
|
|
31
|
+
{type === 'h5p' && <CursorClick style={{ width: '24px', height: '24px' }} />}
|
|
32
|
+
{type === 'iframe' && <CursorClick style={{ width: '24px', height: '24px' }} />}
|
|
33
|
+
{type === 'external' && <CursorClick style={{ width: '24px', height: '24px' }} />}
|
|
34
|
+
{type === 'video' && <Play style={{ width: '24px', height: '24px' }} />}
|
|
35
|
+
</button>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
@@ -136,6 +136,10 @@
|
|
|
136
136
|
justify-content: space-between;
|
|
137
137
|
color: $primary-color;
|
|
138
138
|
}
|
|
139
|
+
.c-figure__byline-author-buttons--no-siblings {
|
|
140
|
+
//styling for button in licensewrapper when there are no other elements in it. Places the button to the right
|
|
141
|
+
justify-content: flex-end;
|
|
142
|
+
}
|
|
139
143
|
.c-figure__byline-authors {
|
|
140
144
|
@include font-size(14px, 20px);
|
|
141
145
|
margin-right: $spacing--small;
|
package/src/Figure/index.ts
CHANGED
|
@@ -11,5 +11,6 @@ export { Figure, FigureCaption };
|
|
|
11
11
|
export { FigureLicenseDialog } from './FigureLicenseDialog';
|
|
12
12
|
export { FigureExpandButton } from './FigureExpandButton';
|
|
13
13
|
export { FigureBylineExpandButton } from './FigureBylineExpandButton';
|
|
14
|
+
export { FigureOpenDialogButton } from './FigureOpenDialogButton';
|
|
14
15
|
|
|
15
16
|
export type { FigureType } from './Figure';
|
package/src/Image/Image.tsx
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import React, { ReactNode } from 'react';
|
|
10
10
|
import styled from '@emotion/styled';
|
|
11
11
|
import LazyLoadImage from './LazyLoadImage';
|
|
12
|
+
|
|
12
13
|
export interface ImageCrop {
|
|
13
14
|
startX: number;
|
|
14
15
|
startY: number;
|
|
@@ -39,7 +40,6 @@ const getSrcSet = (src: string, crop: ImageCrop | undefined, focalPoint: ImageFo
|
|
|
39
40
|
const StyledImageWrapper = styled.div`
|
|
40
41
|
position: relative;
|
|
41
42
|
`;
|
|
42
|
-
|
|
43
43
|
interface Props {
|
|
44
44
|
alt: string;
|
|
45
45
|
src: string;
|
|
@@ -14,7 +14,7 @@ import { WithTranslation, withTranslation } from 'react-i18next';
|
|
|
14
14
|
|
|
15
15
|
// @ts-ignore
|
|
16
16
|
import { Remarkable } from 'remarkable';
|
|
17
|
-
import { CloseButton } from '
|
|
17
|
+
import { CloseButton } from '@ndla/button';
|
|
18
18
|
|
|
19
19
|
export enum MessageBoxType {
|
|
20
20
|
ghost = 'ghost',
|
|
@@ -4,16 +4,45 @@
|
|
|
4
4
|
* This source code is licensed under the GPLv3 license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree. *
|
|
6
6
|
*/
|
|
7
|
+
import styled from '@emotion/styled';
|
|
7
8
|
|
|
8
9
|
import React, { useEffect } from 'react';
|
|
9
10
|
//@ts-ignore
|
|
10
11
|
import { initArticleScripts } from '@ndla/article-scripts';
|
|
11
|
-
import {
|
|
12
|
+
import { useTranslation } from 'react-i18next';
|
|
13
|
+
import { breakpoints, mq, spacing } from '@ndla/core';
|
|
14
|
+
import Notion, { NotionDialogContent, NotionDialogText, NotionDialogLicenses } from '@ndla/notion';
|
|
15
|
+
import { Notion as UINotion } from '.';
|
|
12
16
|
import { NotionImage } from './NotionImage';
|
|
13
17
|
import NotionVisualElement, { NotionVisualElementType } from './NotionVisualElement';
|
|
14
18
|
import FigureNotion from './FigureNotion';
|
|
15
19
|
import { Copyright } from '../types';
|
|
16
20
|
|
|
21
|
+
const ContentWrapper = styled.div<{ adjustSizeToFitWiderPage?: boolean }>`
|
|
22
|
+
position: relative;
|
|
23
|
+
right: auto;
|
|
24
|
+
left: ${(props) => (props.adjustSizeToFitWiderPage ? '0%' : '-16.6666666667%')};
|
|
25
|
+
width: ${(props) => (props.adjustSizeToFitWiderPage ? '100%' : '133.3333333333%')};
|
|
26
|
+
padding-left: 24px;
|
|
27
|
+
padding-right: 24px;
|
|
28
|
+
|
|
29
|
+
${mq.range({ until: breakpoints.tabletWide })} {
|
|
30
|
+
width: 100%;
|
|
31
|
+
left: 0;
|
|
32
|
+
}
|
|
33
|
+
`;
|
|
34
|
+
|
|
35
|
+
const ImageWrapper = styled.div`
|
|
36
|
+
float: right;
|
|
37
|
+
padding-left: ${spacing.normal};
|
|
38
|
+
position: relative;
|
|
39
|
+
|
|
40
|
+
${mq.range({ until: breakpoints.tabletWide })} {
|
|
41
|
+
width: 100%;
|
|
42
|
+
padding-left: 0;
|
|
43
|
+
}
|
|
44
|
+
`;
|
|
45
|
+
|
|
17
46
|
export interface ConceptNotionType {
|
|
18
47
|
id: number;
|
|
19
48
|
copyright?: Partial<Copyright>;
|
|
@@ -21,62 +50,132 @@ export interface ConceptNotionType {
|
|
|
21
50
|
text: string;
|
|
22
51
|
subjectNames?: string[];
|
|
23
52
|
visualElement?: NotionVisualElementType;
|
|
53
|
+
authors: string[];
|
|
54
|
+
source?: string;
|
|
24
55
|
image?: {
|
|
25
56
|
src: string;
|
|
26
57
|
alt: string;
|
|
27
58
|
};
|
|
28
59
|
}
|
|
29
60
|
interface Props {
|
|
61
|
+
type?: 'image' | 'video' | 'h5p' | 'iframe' | 'external';
|
|
30
62
|
concept: ConceptNotionType;
|
|
31
63
|
disableScripts?: boolean;
|
|
64
|
+
hideIconsAndAuthors?: boolean;
|
|
65
|
+
adjustSizeToFitWiderPage?: boolean;
|
|
32
66
|
}
|
|
33
67
|
|
|
34
|
-
const ConceptNotion = ({ concept, disableScripts }: Props) => {
|
|
68
|
+
const ConceptNotion = ({ concept, disableScripts, type, hideIconsAndAuthors, adjustSizeToFitWiderPage }: Props) => {
|
|
35
69
|
const notionId = `notion-${concept.id}`;
|
|
36
70
|
const figureId = `notion-figure-${concept.id}`;
|
|
37
71
|
const visualElementId = `visual-element-${concept.id}`;
|
|
72
|
+
const { t } = useTranslation();
|
|
38
73
|
|
|
39
74
|
useEffect(() => {
|
|
40
75
|
if (!disableScripts) {
|
|
41
76
|
initArticleScripts();
|
|
42
77
|
}
|
|
43
78
|
}, [disableScripts]);
|
|
79
|
+
|
|
44
80
|
return (
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
81
|
+
<ContentWrapper adjustSizeToFitWiderPage={adjustSizeToFitWiderPage}>
|
|
82
|
+
<FigureNotion
|
|
83
|
+
resizeIframe
|
|
84
|
+
id={figureId}
|
|
85
|
+
figureId={visualElementId}
|
|
86
|
+
copyright={concept.copyright}
|
|
87
|
+
licenseString={concept.copyright?.license?.license ?? ''}
|
|
88
|
+
type="concept"
|
|
89
|
+
hideIconsAndAuthors={hideIconsAndAuthors}>
|
|
90
|
+
<UINotion
|
|
91
|
+
id={notionId}
|
|
92
|
+
title={concept.title}
|
|
93
|
+
text={concept.text}
|
|
94
|
+
imageElement={
|
|
95
|
+
concept.visualElement?.resource === 'image' && concept.visualElement.image ? (
|
|
96
|
+
<ImageWrapper>
|
|
97
|
+
<Notion
|
|
98
|
+
id={notionId}
|
|
99
|
+
ariaLabel={t('factbox.open')}
|
|
100
|
+
title={concept.title}
|
|
101
|
+
subTitle={t('searchPage.resultType.notionsHeading')}
|
|
102
|
+
hideBaselineIcon
|
|
103
|
+
content={
|
|
104
|
+
<>
|
|
105
|
+
<NotionDialogContent>
|
|
106
|
+
{concept.visualElement?.resource === 'image' && concept.visualElement.image ? (
|
|
107
|
+
<NotionVisualElement
|
|
108
|
+
visualElement={concept.visualElement}
|
|
109
|
+
id={notionId}
|
|
110
|
+
figureId={figureId}
|
|
111
|
+
/>
|
|
112
|
+
) : undefined}
|
|
113
|
+
<NotionDialogText>{concept.text}</NotionDialogText>
|
|
114
|
+
</NotionDialogContent>
|
|
115
|
+
<NotionDialogLicenses
|
|
116
|
+
license={concept.copyright?.license?.license ?? ''}
|
|
117
|
+
source={concept.source}
|
|
118
|
+
/>
|
|
119
|
+
</>
|
|
120
|
+
}>
|
|
121
|
+
{concept.visualElement.image && (
|
|
122
|
+
<NotionImage
|
|
123
|
+
type={type}
|
|
124
|
+
id={visualElementId}
|
|
125
|
+
src={concept.visualElement.image.src}
|
|
126
|
+
alt={concept.visualElement.image.alt ?? ''}
|
|
127
|
+
imageCopyright={concept.visualElement.copyright}
|
|
128
|
+
/>
|
|
129
|
+
)}
|
|
130
|
+
</Notion>
|
|
131
|
+
</ImageWrapper>
|
|
132
|
+
) : undefined
|
|
133
|
+
}
|
|
134
|
+
visualElement={
|
|
135
|
+
concept.visualElement && concept.visualElement.resource !== 'image' && concept.visualElement.url ? (
|
|
136
|
+
<ImageWrapper>
|
|
137
|
+
<Notion
|
|
138
|
+
id={notionId}
|
|
139
|
+
ariaLabel={t('factbox.open')}
|
|
140
|
+
title={concept.title}
|
|
141
|
+
hideBaselineIcon
|
|
142
|
+
subTitle={t('searchPage.resultType.notionsHeading')}
|
|
143
|
+
content={
|
|
144
|
+
<>
|
|
145
|
+
<NotionDialogContent>
|
|
146
|
+
{concept.visualElement &&
|
|
147
|
+
concept.visualElement?.resource !== 'image' &&
|
|
148
|
+
concept.visualElement.url ? (
|
|
149
|
+
<NotionVisualElement
|
|
150
|
+
visualElement={concept.visualElement}
|
|
151
|
+
id={notionId}
|
|
152
|
+
figureId={figureId}
|
|
153
|
+
/>
|
|
154
|
+
) : undefined}
|
|
155
|
+
|
|
156
|
+
<NotionDialogText>{concept.text}</NotionDialogText>
|
|
157
|
+
</NotionDialogContent>
|
|
158
|
+
<NotionDialogLicenses
|
|
159
|
+
license={concept.copyright?.license?.license ?? ''}
|
|
160
|
+
source={concept.source}
|
|
161
|
+
/>
|
|
162
|
+
</>
|
|
163
|
+
}>
|
|
164
|
+
{concept.image && (
|
|
165
|
+
<NotionImage
|
|
166
|
+
type={type}
|
|
167
|
+
id={visualElementId}
|
|
168
|
+
src={concept.image?.src}
|
|
169
|
+
alt={concept.image?.alt ?? ''}
|
|
170
|
+
imageCopyright={concept.visualElement.copyright}
|
|
171
|
+
/>
|
|
172
|
+
)}
|
|
173
|
+
</Notion>
|
|
174
|
+
</ImageWrapper>
|
|
175
|
+
) : undefined
|
|
176
|
+
}></UINotion>
|
|
177
|
+
</FigureNotion>
|
|
178
|
+
</ContentWrapper>
|
|
80
179
|
);
|
|
81
180
|
};
|
|
82
181
|
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree. *
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import Button from '@ndla/button';
|
|
9
8
|
import { getGroupedContributorDescriptionList, getLicenseByAbbreviation } from '@ndla/licenses';
|
|
10
9
|
import React, { ReactNode } from 'react';
|
|
11
10
|
import { useTranslation } from 'react-i18next';
|
|
@@ -17,11 +16,12 @@ interface Props {
|
|
|
17
16
|
figureId: string;
|
|
18
17
|
children: ReactNode | ((params: { typeClass: string }) => ReactNode);
|
|
19
18
|
id: string;
|
|
20
|
-
title
|
|
19
|
+
title?: string;
|
|
21
20
|
copyright?: Partial<Copyright>;
|
|
22
21
|
licenseString: string;
|
|
23
22
|
type: 'video' | 'h5p' | 'image' | 'concept';
|
|
24
23
|
hideFigCaption?: boolean;
|
|
24
|
+
hideIconsAndAuthors?: boolean;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
const FigureNotion = ({
|
|
@@ -34,6 +34,7 @@ const FigureNotion = ({
|
|
|
34
34
|
title,
|
|
35
35
|
type,
|
|
36
36
|
hideFigCaption,
|
|
37
|
+
hideIconsAndAuthors,
|
|
37
38
|
}: Props) => {
|
|
38
39
|
const { t, i18n } = useTranslation();
|
|
39
40
|
const license = getLicenseByAbbreviation(licenseString, i18n.language);
|
|
@@ -59,7 +60,8 @@ const FigureNotion = ({
|
|
|
59
60
|
id={id}
|
|
60
61
|
reuseLabel={t(`${type}.reuse`)}
|
|
61
62
|
authors={contributors}
|
|
62
|
-
licenseRights={license.rights}
|
|
63
|
+
licenseRights={license.rights}
|
|
64
|
+
hideIconsAndAuthors={hideIconsAndAuthors}>
|
|
63
65
|
<FigureLicenseDialog
|
|
64
66
|
id={id}
|
|
65
67
|
authors={contributors}
|
|
@@ -73,9 +75,7 @@ const FigureNotion = ({
|
|
|
73
75
|
source: t('source'),
|
|
74
76
|
learnAboutLicenses: t('license.learnMore'),
|
|
75
77
|
title: t('title'),
|
|
76
|
-
}}>
|
|
77
|
-
{type === 'image' && <Button outline>{t('license.copyTitle')}</Button>}
|
|
78
|
-
</FigureLicenseDialog>
|
|
78
|
+
}}></FigureLicenseDialog>
|
|
79
79
|
</FigureCaption>
|
|
80
80
|
)}
|
|
81
81
|
</>
|
package/src/Notion/Notion.tsx
CHANGED
|
@@ -5,17 +5,11 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
-
|
|
8
|
+
import React, { Fragment, ReactNode } from 'react';
|
|
9
9
|
import styled from '@emotion/styled';
|
|
10
10
|
import { useTranslation } from 'react-i18next';
|
|
11
11
|
import { parseMarkdown } from '@ndla/util';
|
|
12
|
-
import
|
|
13
|
-
import { keyframes } from '@emotion/core';
|
|
14
|
-
import Button from '@ndla/button';
|
|
15
|
-
import { animations, breakpoints, colors, fonts, mq, spacing } from '@ndla/core';
|
|
16
|
-
import { CursorClick } from '@ndla/icons/action';
|
|
17
|
-
import { Play, ArrowCollapse } from '@ndla/icons/common';
|
|
18
|
-
import { ImageCrop, ImageFocalPoint, makeSrcQueryString } from '../Image';
|
|
12
|
+
import { breakpoints, fonts, mq, spacing } from '@ndla/core';
|
|
19
13
|
|
|
20
14
|
const NotionContainer = styled.div``;
|
|
21
15
|
|
|
@@ -26,11 +20,7 @@ const ContentWrapper = styled.div`
|
|
|
26
20
|
}
|
|
27
21
|
.c-figure {
|
|
28
22
|
margin: 0;
|
|
29
|
-
position: relative !important;
|
|
30
|
-
left: 0 !important;
|
|
31
|
-
width: 25% !important;
|
|
32
23
|
padding: 0 0 0 20px;
|
|
33
|
-
float: right;
|
|
34
24
|
&.expanded {
|
|
35
25
|
width: 100% !important;
|
|
36
26
|
padding: 0;
|
|
@@ -44,114 +34,21 @@ const ContentWrapper = styled.div`
|
|
|
44
34
|
`;
|
|
45
35
|
const TextWrapper = styled.div<{ hasVisualElement: boolean }>`
|
|
46
36
|
width: ${(props) => (props.hasVisualElement ? '75%' : '100%')};
|
|
37
|
+
|
|
47
38
|
${mq.range({ until: breakpoints.tabletWide })} {
|
|
48
39
|
width: 100%;
|
|
49
40
|
}
|
|
50
|
-
font-family: ${fonts.
|
|
41
|
+
font-family: ${fonts.sans};
|
|
51
42
|
${fonts.sizes('18px', '28px')};
|
|
52
43
|
${ContentWrapper} .c-figure.expanded + & {
|
|
53
44
|
width: 100%;
|
|
54
45
|
}
|
|
55
46
|
`;
|
|
56
47
|
|
|
57
|
-
const ImageElement = styled.img``;
|
|
58
|
-
|
|
59
|
-
const fadeInMediaKeyframe = keyframes`
|
|
60
|
-
0% {
|
|
61
|
-
opacity: 0;
|
|
62
|
-
height: auto;
|
|
63
|
-
}
|
|
64
|
-
100% {
|
|
65
|
-
opacity: 1;
|
|
66
|
-
}
|
|
67
|
-
`;
|
|
68
|
-
const fadeOutMediaKeyframe = keyframes`
|
|
69
|
-
0% {
|
|
70
|
-
opacity: 1;
|
|
71
|
-
height: auto;
|
|
72
|
-
}
|
|
73
|
-
100% {
|
|
74
|
-
opacity: 0;
|
|
75
|
-
height:0;
|
|
76
|
-
overflow: hidden;
|
|
77
|
-
}
|
|
78
|
-
`;
|
|
79
|
-
|
|
80
|
-
const ImageWrapper = styled.div`
|
|
81
|
-
float: right;
|
|
82
|
-
width: 25%;
|
|
83
|
-
padding-left: ${spacing.normal};
|
|
84
|
-
position: relative;
|
|
85
|
-
|
|
86
|
-
${mq.range({ until: breakpoints.tabletWide })} {
|
|
87
|
-
width: 100%;
|
|
88
|
-
padding-left: 0;
|
|
89
|
-
}
|
|
90
|
-
`;
|
|
91
|
-
|
|
92
|
-
const ExpandVisualElementButton = styled(Button)`
|
|
93
|
-
position: absolute;
|
|
94
|
-
right: 8px;
|
|
95
|
-
bottom: 8px;
|
|
96
|
-
transition: all ${animations.durations.normal};
|
|
97
|
-
&,
|
|
98
|
-
&:focus,
|
|
99
|
-
&:active {
|
|
100
|
-
background-color: rgba(255, 255, 255, 0.65);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
color: ${colors.brand.primary};
|
|
104
|
-
border-radius: 50%;
|
|
105
|
-
border: 0;
|
|
106
|
-
width: 40px;
|
|
107
|
-
height: 40px;
|
|
108
|
-
display: inline-flex;
|
|
109
|
-
justify-content: center;
|
|
110
|
-
align-items: center;
|
|
111
|
-
|
|
112
|
-
svg {
|
|
113
|
-
transition: transform ${animations.durations.normal} ease-out;
|
|
114
|
-
}
|
|
115
|
-
${ContentWrapper}:hover & {
|
|
116
|
-
background-color: #fff;
|
|
117
|
-
svg {
|
|
118
|
-
transform: scale(1.2);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
`;
|
|
122
|
-
|
|
123
|
-
const ExpandIcon = styled.span`
|
|
124
|
-
${ExpandVisualElementButton}.expanded & {
|
|
125
|
-
display: none;
|
|
126
|
-
}
|
|
127
|
-
`;
|
|
128
|
-
const CollapseIcon = styled.span`
|
|
129
|
-
display: none;
|
|
130
|
-
${ExpandVisualElementButton}.expanded & {
|
|
131
|
-
display: inline-block;
|
|
132
|
-
}
|
|
133
|
-
`;
|
|
134
|
-
|
|
135
48
|
const ClearWrapper = styled.div`
|
|
136
49
|
clear: both;
|
|
137
50
|
`;
|
|
138
51
|
|
|
139
|
-
const MediaContainer = styled.div`
|
|
140
|
-
opacity: 0;
|
|
141
|
-
height: 0;
|
|
142
|
-
overflow: hidden;
|
|
143
|
-
&.expanded {
|
|
144
|
-
animation-name: ${fadeInMediaKeyframe};
|
|
145
|
-
animation-duration: 2.8s;
|
|
146
|
-
opacity: 1;
|
|
147
|
-
height: auto;
|
|
148
|
-
}
|
|
149
|
-
&.fadeOut {
|
|
150
|
-
animation-name: ${fadeOutMediaKeyframe};
|
|
151
|
-
animation-duration: 2.8s;
|
|
152
|
-
}
|
|
153
|
-
`;
|
|
154
|
-
|
|
155
52
|
const LabelsContainer = styled.div`
|
|
156
53
|
display: flex;
|
|
157
54
|
align-items: center;
|
|
@@ -160,23 +57,12 @@ const LabelsContainer = styled.div`
|
|
|
160
57
|
margin: ${spacing.small} 0;
|
|
161
58
|
`;
|
|
162
59
|
|
|
163
|
-
type VisualElementProps = {
|
|
164
|
-
type: 'video' | 'other';
|
|
165
|
-
element: ReactNode;
|
|
166
|
-
metaImage?: {
|
|
167
|
-
url: string;
|
|
168
|
-
alt: string;
|
|
169
|
-
crop?: ImageCrop;
|
|
170
|
-
focalPoint?: ImageFocalPoint;
|
|
171
|
-
};
|
|
172
|
-
};
|
|
173
|
-
|
|
174
60
|
export type NotionProps = {
|
|
175
61
|
id: string | number;
|
|
176
62
|
labels?: string[];
|
|
177
63
|
text: ReactNode;
|
|
178
64
|
title: string;
|
|
179
|
-
visualElement
|
|
65
|
+
visualElement: ReactNode;
|
|
180
66
|
imageElement?: ReactNode;
|
|
181
67
|
children?: ReactNode;
|
|
182
68
|
};
|
|
@@ -186,34 +72,10 @@ const Notion = ({ id, labels = [], text, title, visualElement, imageElement, chi
|
|
|
186
72
|
|
|
187
73
|
return (
|
|
188
74
|
<NotionContainer>
|
|
189
|
-
{visualElement && <MediaContainer id={`notion-media-${id}`}>{visualElement.element}</MediaContainer>}
|
|
190
75
|
<ContentWrapper>
|
|
191
76
|
{imageElement}
|
|
192
|
-
{visualElement
|
|
193
|
-
|
|
194
|
-
<ImageElement
|
|
195
|
-
src={`${visualElement.metaImage.url}?${makeSrcQueryString(
|
|
196
|
-
400,
|
|
197
|
-
visualElement.metaImage.crop,
|
|
198
|
-
visualElement.metaImage.focalPoint,
|
|
199
|
-
)}`}
|
|
200
|
-
alt={visualElement.metaImage.alt}
|
|
201
|
-
/>
|
|
202
|
-
<ExpandVisualElementButton
|
|
203
|
-
stripped
|
|
204
|
-
data-notion-expand-media={true}
|
|
205
|
-
data-notion-media-id={`notion-media-${id}`}>
|
|
206
|
-
<ExpandIcon>
|
|
207
|
-
{visualElement.type === 'video' && <Play style={{ width: '24px', height: '24px' }} />}
|
|
208
|
-
{visualElement.type === 'other' && <CursorClick style={{ width: '24px', height: '24px' }} />}
|
|
209
|
-
</ExpandIcon>
|
|
210
|
-
<CollapseIcon>
|
|
211
|
-
<ArrowCollapse style={{ width: '24px', height: '24px' }} />
|
|
212
|
-
</CollapseIcon>
|
|
213
|
-
</ExpandVisualElementButton>
|
|
214
|
-
</ImageWrapper>
|
|
215
|
-
)}
|
|
216
|
-
<TextWrapper hasVisualElement={!!(imageElement || visualElement?.metaImage)}>
|
|
77
|
+
{visualElement}
|
|
78
|
+
<TextWrapper hasVisualElement={!!(imageElement || visualElement)}>
|
|
217
79
|
{parseMarkdown(`**${title}** \u2013 ${text}`, 'body')}
|
|
218
80
|
{!!labels.length && (
|
|
219
81
|
<LabelsContainer>
|
|
@@ -6,17 +6,44 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import React from 'react';
|
|
9
|
+
import styled from '@emotion/styled';
|
|
10
|
+
import { animations, breakpoints, mq, spacing } from '@ndla/core';
|
|
9
11
|
import { useTranslation } from 'react-i18next';
|
|
10
|
-
import { Image,
|
|
12
|
+
import { Image, FigureOpenDialogButton } from '..';
|
|
11
13
|
import { Copyright } from '../types';
|
|
12
14
|
import FigureNotion from './FigureNotion';
|
|
15
|
+
|
|
16
|
+
const StyledImageWrapper = styled.div`
|
|
17
|
+
overflow: hidden;
|
|
18
|
+
width: 260px;
|
|
19
|
+
padding-top: ${spacing.small};
|
|
20
|
+
${mq.range({ until: breakpoints.tabletWide })} {
|
|
21
|
+
margin: 0 auto;
|
|
22
|
+
}
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
const StyledImage = styled(Image)`
|
|
26
|
+
object-fit: cover;
|
|
27
|
+
max-height: 162px;
|
|
28
|
+
transition: transform ${animations.durations.fast};
|
|
29
|
+
&:hover {
|
|
30
|
+
transform: scale(1.1);
|
|
31
|
+
opacity: 1.1;
|
|
32
|
+
transition-duration: 0.5s;
|
|
33
|
+
}
|
|
34
|
+
${mq.range({ until: breakpoints.tabletWide })} {
|
|
35
|
+
min-width: 260px;
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
38
|
+
|
|
13
39
|
interface Props {
|
|
40
|
+
type?: 'image' | 'video' | 'h5p' | 'iframe' | 'external';
|
|
14
41
|
id: string;
|
|
15
42
|
src: string;
|
|
16
43
|
alt: string;
|
|
17
44
|
imageCopyright?: Partial<Copyright>;
|
|
18
45
|
}
|
|
19
|
-
export const NotionImage = ({ id, src, alt, imageCopyright }: Props) => {
|
|
46
|
+
export const NotionImage = ({ id, src, alt, imageCopyright, type }: Props) => {
|
|
20
47
|
const { t } = useTranslation();
|
|
21
48
|
|
|
22
49
|
const imageId = `image-${id}`;
|
|
@@ -32,19 +59,21 @@ export const NotionImage = ({ id, src, alt, imageCopyright }: Props) => {
|
|
|
32
59
|
licenseString={imageCopyright?.license?.license ?? ''}
|
|
33
60
|
type={'image'}>
|
|
34
61
|
{({ typeClass }) => (
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
62
|
+
<StyledImageWrapper>
|
|
63
|
+
<StyledImage
|
|
64
|
+
alt={alt}
|
|
65
|
+
src={src}
|
|
66
|
+
expandButton={
|
|
67
|
+
<FigureOpenDialogButton
|
|
68
|
+
type={type}
|
|
69
|
+
messages={{
|
|
70
|
+
zoomImageButtonLabel: t('license.images.itemImage.zoomImageButtonLabel'),
|
|
71
|
+
zoomOutImageButtonLabel: t('license.image.itemImage.zoomOutImageButtonLabel'),
|
|
72
|
+
}}
|
|
73
|
+
/>
|
|
74
|
+
}
|
|
75
|
+
/>
|
|
76
|
+
</StyledImageWrapper>
|
|
48
77
|
)}
|
|
49
78
|
</FigureNotion>
|
|
50
79
|
);
|