@ndla/ui 53.0.1 → 54.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/ArticleByline.js +15 -7
- package/es/Article/ArticleParagraph.js +5 -5
- package/es/BlogPost/BlogPost.js +6 -5
- package/es/CampaignBlock/CampaignBlock.js +7 -7
- package/es/CodeBlock/CodeBlock.js +4 -4
- package/es/Embed/ConceptEmbed.js +14 -8
- package/es/Embed/RelatedContentEmbed.js +2 -1
- package/es/ErrorMessage/ErrorMessage.js +14 -17
- package/es/Figure/Figure.js +36 -20
- package/es/KeyFigure/KeyFigure.js +5 -5
- package/es/Layout/LayoutItem.js +20 -6
- package/es/Layout/index.js +0 -1
- package/es/List/OrderedList.js +12 -11
- package/es/MyNdla/Resource/Folder.js +37 -24
- package/es/ResourceBox/ResourceBox.js +6 -6
- package/es/Search/SearchResultSleeve.js +11 -11
- package/es/Table/Table.js +6 -6
- package/es/TreeStructure/AddFolderButton.js +2 -2
- package/es/TreeStructure/ComboboxButton.js +2 -2
- package/es/TreeStructure/FolderItem.js +7 -7
- package/es/TreeStructure/FolderItems.js +2 -2
- package/es/TreeStructure/TreeStructure.js +5 -5
- package/es/all.css +1 -1
- package/es/index.js +1 -1
- package/es/locale/messages-en.js +17 -3
- package/es/locale/messages-nb.js +17 -3
- package/es/locale/messages-nn.js +18 -4
- package/es/locale/messages-se.js +17 -3
- package/es/locale/messages-sma.js +17 -3
- package/lib/Article/ArticleByline.js +15 -7
- package/lib/Article/ArticleParagraph.js +5 -5
- package/lib/BlogPost/BlogPost.js +6 -5
- package/lib/CampaignBlock/CampaignBlock.js +7 -7
- package/lib/CodeBlock/CodeBlock.js +4 -4
- package/lib/Embed/ConceptEmbed.d.ts +1 -0
- package/lib/Embed/ConceptEmbed.js +14 -8
- package/lib/Embed/RelatedContentEmbed.js +3 -1
- package/lib/ErrorMessage/ErrorMessage.js +14 -17
- package/lib/Figure/Figure.js +40 -20
- package/lib/KeyFigure/KeyFigure.js +5 -5
- package/lib/Layout/LayoutItem.js +20 -8
- package/lib/Layout/index.d.ts +0 -1
- package/lib/Layout/index.js +0 -7
- package/lib/List/OrderedList.d.ts +0 -1
- package/lib/List/OrderedList.js +12 -12
- package/lib/MyNdla/Resource/Folder.d.ts +3 -1
- package/lib/MyNdla/Resource/Folder.js +35 -22
- package/lib/ResourceBox/ResourceBox.js +6 -6
- package/lib/Search/SearchResultSleeve.js +11 -11
- package/lib/Table/Table.js +6 -6
- package/lib/TreeStructure/AddFolderButton.d.ts +1 -1
- package/lib/TreeStructure/AddFolderButton.js +2 -2
- package/lib/TreeStructure/ComboboxButton.d.ts +1 -1
- package/lib/TreeStructure/ComboboxButton.js +2 -2
- package/lib/TreeStructure/FolderItem.d.ts +1 -1
- package/lib/TreeStructure/FolderItem.js +7 -7
- package/lib/TreeStructure/FolderItems.d.ts +1 -1
- package/lib/TreeStructure/FolderItems.js +2 -2
- package/lib/TreeStructure/TreeStructure.d.ts +1 -1
- package/lib/TreeStructure/TreeStructure.js +5 -5
- package/lib/TreeStructure/arrowNavigation.d.ts +1 -1
- package/lib/TreeStructure/helperFunctions.d.ts +1 -1
- package/lib/TreeStructure/types.d.ts +1 -1
- package/lib/all.css +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +0 -6
- package/lib/locale/messages-en.d.ts +14 -0
- package/lib/locale/messages-en.js +17 -3
- package/lib/locale/messages-nb.d.ts +14 -0
- package/lib/locale/messages-nb.js +17 -3
- package/lib/locale/messages-nn.d.ts +15 -1
- package/lib/locale/messages-nn.js +18 -4
- package/lib/locale/messages-se.d.ts +14 -0
- package/lib/locale/messages-se.js +17 -3
- package/lib/locale/messages-sma.d.ts +14 -0
- package/lib/locale/messages-sma.js +17 -3
- package/package.json +16 -15
- package/src/Article/ArticleByline.tsx +9 -2
- package/src/Article/ArticleParagraph.tsx +3 -0
- package/src/BlogPost/BlogPost.tsx +2 -1
- package/src/CampaignBlock/CampaignBlock.tsx +1 -1
- package/src/CodeBlock/CodeBlock.tsx +1 -1
- package/src/Embed/AudioEmbed.stories.tsx +3 -3
- package/src/Embed/BrightcoveEmbed.stories.tsx +3 -3
- package/src/Embed/ConceptEmbed.stories.tsx +3 -3
- package/src/Embed/ConceptEmbed.tsx +20 -2
- package/src/Embed/ExternalEmbed.stories.tsx +3 -3
- package/src/Embed/H5pEmbed.stories.tsx +3 -3
- package/src/Embed/IframeEmbed.stories.tsx +3 -3
- package/src/Embed/ImageEmbed.stories.tsx +3 -3
- package/src/Embed/RelatedContentEmbed.stories.tsx +15 -3
- package/src/Embed/RelatedContentEmbed.tsx +4 -1
- package/src/Embed/UuDisclaimerEmbed.stories.tsx +3 -3
- package/src/ErrorMessage/ErrorMessage.tsx +8 -4
- package/src/Figure/Figure.tsx +102 -24
- package/src/KeyFigure/KeyFigure.tsx +1 -1
- package/src/Layout/LayoutItem.tsx +23 -6
- package/src/Layout/index.ts +0 -1
- package/src/List/OrderedList.stories.tsx +2 -2
- package/src/List/OrderedList.tsx +21 -18
- package/src/MyNdla/Resource/Folder.stories.tsx +5 -0
- package/src/MyNdla/Resource/Folder.tsx +41 -8
- package/src/ResourceBox/ResourceBox.tsx +2 -2
- package/src/Search/SearchResultSleeve.tsx +3 -3
- package/src/Table/Table.stories.tsx +39 -0
- package/src/Table/Table.tsx +11 -0
- package/src/TreeStructure/AddFolderButton.tsx +1 -1
- package/src/TreeStructure/ComboboxButton.tsx +1 -1
- package/src/TreeStructure/FolderItem.tsx +2 -2
- package/src/TreeStructure/FolderItems.tsx +1 -1
- package/src/TreeStructure/TreeStructure.stories.tsx +1 -1
- package/src/TreeStructure/TreeStructure.tsx +1 -1
- package/src/TreeStructure/arrowNavigation.ts +1 -1
- package/src/TreeStructure/helperFunctions.ts +1 -1
- package/src/TreeStructure/types.ts +1 -1
- package/src/index.ts +1 -1
- package/src/locale/messages-en.ts +14 -0
- package/src/locale/messages-nb.ts +14 -0
- package/src/locale/messages-nn.ts +15 -1
- package/src/locale/messages-se.ts +14 -0
- package/src/locale/messages-sma.ts +14 -0
- package/es/Layout/Content.js +0 -19
- package/lib/Layout/Content.d.ts +0 -13
- package/lib/Layout/Content.js +0 -26
- package/src/Layout/Content.tsx +0 -17
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import { TFunction } from "i18next";
|
|
10
10
|
import { ReactNode, useCallback, useEffect, useState } from "react";
|
|
11
11
|
import { useTranslation } from "react-i18next";
|
|
12
|
+
import { useLocation } from "react-router-dom";
|
|
12
13
|
import styled from "@emotion/styled";
|
|
13
14
|
import { AccordionRoot, AccordionHeader, AccordionContent, AccordionItem } from "@ndla/accordion";
|
|
14
15
|
import { breakpoints, colors, fonts, mq, spacing } from "@ndla/core";
|
|
@@ -103,7 +104,7 @@ const LicenseWrapper = styled.div`
|
|
|
103
104
|
|
|
104
105
|
const StyledAccordionHeader = styled(AccordionHeader)`
|
|
105
106
|
background-color: ${colors.brand.lightest};
|
|
106
|
-
|
|
107
|
+
${fonts.sizes("16px", "29px")};
|
|
107
108
|
font-weight: ${fonts.weight.semibold};
|
|
108
109
|
|
|
109
110
|
&[data-background-color="white"][data-state="closed"] {
|
|
@@ -133,7 +134,9 @@ const ArticleByline = ({
|
|
|
133
134
|
bylineType = "article",
|
|
134
135
|
}: Props) => {
|
|
135
136
|
const { t } = useTranslation();
|
|
137
|
+
const { pathname } = useLocation();
|
|
136
138
|
const [openAccordions, setOpenAccordions] = useState<string[]>([]);
|
|
139
|
+
const accordionItemValue = "rulesForUse";
|
|
137
140
|
|
|
138
141
|
const onHashChange = useCallback(
|
|
139
142
|
(e: HashChangeEvent) => {
|
|
@@ -148,6 +151,10 @@ const ArticleByline = ({
|
|
|
148
151
|
[openAccordions],
|
|
149
152
|
);
|
|
150
153
|
|
|
154
|
+
useEffect(() => {
|
|
155
|
+
setOpenAccordions((prev) => prev.filter((state) => state !== accordionItemValue));
|
|
156
|
+
}, [pathname]);
|
|
157
|
+
|
|
151
158
|
useEffect(() => {
|
|
152
159
|
window.addEventListener("hashchange", onHashChange);
|
|
153
160
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
@@ -181,7 +188,7 @@ const ArticleByline = ({
|
|
|
181
188
|
)}
|
|
182
189
|
<AccordionRoot type="multiple" onValueChange={setOpenAccordions} value={openAccordions}>
|
|
183
190
|
{licenseBox && (
|
|
184
|
-
<AccordionItem value=
|
|
191
|
+
<AccordionItem value={accordionItemValue}>
|
|
185
192
|
<StyledAccordionHeader headingLevel="h2" data-background-color={accordionHeaderVariant}>
|
|
186
193
|
{t("article.useContent")}
|
|
187
194
|
</StyledAccordionHeader>
|
|
@@ -84,12 +84,13 @@ const StyledImg = styled.img`
|
|
|
84
84
|
const BlogPost = ({ title, author, url, metaImage, headingLevel: Heading = "h3", size = "normal", path }: Props) => {
|
|
85
85
|
const { t } = useTranslation();
|
|
86
86
|
const href = getPossiblyRelativeUrl(url, path);
|
|
87
|
+
const imageWidth = size === "large" ? 532 : 350;
|
|
87
88
|
return (
|
|
88
89
|
<Container data-size={size} to={href}>
|
|
89
90
|
<Heading className="blog-title" css={headingCss}>
|
|
90
91
|
{parse(title)}
|
|
91
92
|
</Heading>
|
|
92
|
-
<StyledImg src={metaImage.url} alt={metaImage.alt} />
|
|
93
|
+
<StyledImg src={`${metaImage.url}?width=${imageWidth}`} alt={metaImage.alt} />
|
|
93
94
|
{!!author && <AuthorContainer aria-label={t("article.writtenBy", { authors: author })}>{author}</AuthorContainer>}
|
|
94
95
|
</Container>
|
|
95
96
|
);
|
|
@@ -91,7 +91,7 @@ const CampaignBlock = ({
|
|
|
91
91
|
}: Props) => {
|
|
92
92
|
return (
|
|
93
93
|
<Container className={className} data-type="campaign-block" data-image-side={imageSide}>
|
|
94
|
-
{image && <StyledImg src={image.src} height={200} width={240} alt={image.alt} />}
|
|
94
|
+
{image && <StyledImg src={`${image.src}?width=240`} height={200} width={240} alt={image.alt} />}
|
|
95
95
|
<TextWrapper>
|
|
96
96
|
<Heading css={headingStyle}>{parse(title)}</Heading>
|
|
97
97
|
<StyledDescription>{parse(description)}</StyledDescription>
|
|
@@ -11,7 +11,7 @@ import { AudioEmbedData, AudioMeta } from "@ndla/types-embed";
|
|
|
11
11
|
import AudioEmbed from "./AudioEmbed";
|
|
12
12
|
import StoryFavoriteButton from "../../../../stories/StoryFavoriteButton";
|
|
13
13
|
import { ArticleWrapper } from "../Article";
|
|
14
|
-
import { OneColumn } from "../Layout";
|
|
14
|
+
import LayoutItem, { OneColumn } from "../Layout";
|
|
15
15
|
|
|
16
16
|
const embedData: AudioEmbedData = {
|
|
17
17
|
resource: "audio",
|
|
@@ -190,11 +190,11 @@ const meta: Meta<typeof AudioEmbed> = {
|
|
|
190
190
|
(Story) => (
|
|
191
191
|
<OneColumn>
|
|
192
192
|
<ArticleWrapper modifier="clean">
|
|
193
|
-
<
|
|
193
|
+
<LayoutItem layout="center">
|
|
194
194
|
<section>
|
|
195
195
|
<Story />
|
|
196
196
|
</section>
|
|
197
|
-
</
|
|
197
|
+
</LayoutItem>
|
|
198
198
|
</ArticleWrapper>
|
|
199
199
|
</OneColumn>
|
|
200
200
|
),
|
|
@@ -11,7 +11,7 @@ import { BrightcoveData, BrightcoveEmbedData, BrightcoveMetaData } from "@ndla/t
|
|
|
11
11
|
import BrightcoveEmbed from "./BrightcoveEmbed";
|
|
12
12
|
import StoryFavoriteButton from "../../../../stories/StoryFavoriteButton";
|
|
13
13
|
import { ArticleWrapper } from "../Article";
|
|
14
|
-
import { OneColumn } from "../Layout";
|
|
14
|
+
import LayoutItem, { OneColumn } from "../Layout";
|
|
15
15
|
|
|
16
16
|
const embedData: BrightcoveEmbedData = {
|
|
17
17
|
resource: "brightcove",
|
|
@@ -163,11 +163,11 @@ const meta: Meta<typeof BrightcoveEmbed> = {
|
|
|
163
163
|
(Story) => (
|
|
164
164
|
<OneColumn>
|
|
165
165
|
<ArticleWrapper modifier="clean">
|
|
166
|
-
<
|
|
166
|
+
<LayoutItem layout="center">
|
|
167
167
|
<section>
|
|
168
168
|
<Story />
|
|
169
169
|
</section>
|
|
170
|
-
</
|
|
170
|
+
</LayoutItem>
|
|
171
171
|
</ArticleWrapper>
|
|
172
172
|
</OneColumn>
|
|
173
173
|
),
|
|
@@ -11,7 +11,7 @@ import { ConceptData, ConceptEmbedData } from "@ndla/types-embed";
|
|
|
11
11
|
import ConceptEmbed from "./ConceptEmbed";
|
|
12
12
|
import StoryFavoriteButton from "../../../../stories/StoryFavoriteButton";
|
|
13
13
|
import { ArticleWrapper } from "../Article";
|
|
14
|
-
import { OneColumn } from "../Layout";
|
|
14
|
+
import LayoutItem, { OneColumn } from "../Layout";
|
|
15
15
|
|
|
16
16
|
const blockEmbedData: ConceptEmbedData = {
|
|
17
17
|
contentId: "35",
|
|
@@ -235,11 +235,11 @@ const meta: Meta<typeof ConceptEmbed> = {
|
|
|
235
235
|
(Story) => (
|
|
236
236
|
<OneColumn>
|
|
237
237
|
<ArticleWrapper modifier="clean">
|
|
238
|
-
<
|
|
238
|
+
<LayoutItem layout="center">
|
|
239
239
|
<section>
|
|
240
240
|
<Story />
|
|
241
241
|
</section>
|
|
242
|
-
</
|
|
242
|
+
</LayoutItem>
|
|
243
243
|
</ArticleWrapper>
|
|
244
244
|
</OneColumn>
|
|
245
245
|
),
|
|
@@ -177,6 +177,7 @@ interface InlineConceptProps extends ConceptNotionData {
|
|
|
177
177
|
conceptHeartButton?: ReactNode;
|
|
178
178
|
exampleIds?: string;
|
|
179
179
|
exampleLangs?: string;
|
|
180
|
+
setSelection?: (e: MouseEvent) => void;
|
|
180
181
|
}
|
|
181
182
|
|
|
182
183
|
const NotionButton = styled.span`
|
|
@@ -238,6 +239,7 @@ export const InlineConcept = forwardRef<HTMLSpanElement, InlineConceptProps>(
|
|
|
238
239
|
lang,
|
|
239
240
|
exampleIds,
|
|
240
241
|
exampleLangs,
|
|
242
|
+
setSelection,
|
|
241
243
|
...rest
|
|
242
244
|
},
|
|
243
245
|
ref,
|
|
@@ -258,13 +260,29 @@ export const InlineConcept = forwardRef<HTMLSpanElement, InlineConceptProps>(
|
|
|
258
260
|
}
|
|
259
261
|
}, []);
|
|
260
262
|
|
|
263
|
+
const preventAutoFocusInEditor = useCallback(
|
|
264
|
+
(e: MouseEvent) => {
|
|
265
|
+
e.preventDefault();
|
|
266
|
+
e.stopPropagation();
|
|
267
|
+
setSelection?.(e);
|
|
268
|
+
},
|
|
269
|
+
[setSelection],
|
|
270
|
+
);
|
|
271
|
+
|
|
261
272
|
return (
|
|
262
273
|
<Root modal={isMobile} onOpenChange={onOpenChange}>
|
|
263
274
|
<StyledAnchor ref={anchorRef} asChild>
|
|
264
275
|
<StyledAnchorSpan contentEditable={false} />
|
|
265
276
|
</StyledAnchor>
|
|
266
|
-
<Trigger asChild
|
|
267
|
-
<NotionButton
|
|
277
|
+
<Trigger asChild>
|
|
278
|
+
<NotionButton
|
|
279
|
+
onMouseDown={(e) => (setSelection ? preventAutoFocusInEditor(e.nativeEvent) : undefined)}
|
|
280
|
+
data-open={modalPos !== -9999}
|
|
281
|
+
role="button"
|
|
282
|
+
tabIndex={0}
|
|
283
|
+
ref={ref}
|
|
284
|
+
{...rest}
|
|
285
|
+
>
|
|
268
286
|
{linkText}
|
|
269
287
|
</NotionButton>
|
|
270
288
|
</Trigger>
|
|
@@ -10,7 +10,7 @@ import { Meta, StoryObj } from "@storybook/react";
|
|
|
10
10
|
import { OembedEmbedData, OembedData } from "@ndla/types-embed";
|
|
11
11
|
import ExternalEmbed from "./ExternalEmbed";
|
|
12
12
|
import { ArticleWrapper } from "../Article";
|
|
13
|
-
import { OneColumn } from "../Layout";
|
|
13
|
+
import LayoutItem, { OneColumn } from "../Layout";
|
|
14
14
|
|
|
15
15
|
const embedData: OembedEmbedData = {
|
|
16
16
|
resource: "external",
|
|
@@ -57,11 +57,11 @@ const meta: Meta<typeof ExternalEmbed> = {
|
|
|
57
57
|
(Story) => (
|
|
58
58
|
<OneColumn>
|
|
59
59
|
<ArticleWrapper modifier="clean">
|
|
60
|
-
<
|
|
60
|
+
<LayoutItem layout="center">
|
|
61
61
|
<section>
|
|
62
62
|
<Story />
|
|
63
63
|
</section>
|
|
64
|
-
</
|
|
64
|
+
</LayoutItem>
|
|
65
65
|
</ArticleWrapper>
|
|
66
66
|
</OneColumn>
|
|
67
67
|
),
|
|
@@ -10,7 +10,7 @@ import { Meta, StoryObj } from "@storybook/react";
|
|
|
10
10
|
import { H5pEmbedData, H5pData } from "@ndla/types-embed";
|
|
11
11
|
import H5pEmbed from "./H5pEmbed";
|
|
12
12
|
import { ArticleWrapper } from "../Article";
|
|
13
|
-
import { OneColumn } from "../Layout";
|
|
13
|
+
import LayoutItem, { OneColumn } from "../Layout";
|
|
14
14
|
|
|
15
15
|
const embedData: H5pEmbedData = {
|
|
16
16
|
resource: "h5p",
|
|
@@ -54,11 +54,11 @@ const meta: Meta<typeof H5pEmbed> = {
|
|
|
54
54
|
(Story) => (
|
|
55
55
|
<OneColumn>
|
|
56
56
|
<ArticleWrapper modifier="clean">
|
|
57
|
-
<
|
|
57
|
+
<LayoutItem layout="center">
|
|
58
58
|
<section>
|
|
59
59
|
<Story />
|
|
60
60
|
</section>
|
|
61
|
-
</
|
|
61
|
+
</LayoutItem>
|
|
62
62
|
</ArticleWrapper>
|
|
63
63
|
</OneColumn>
|
|
64
64
|
),
|
|
@@ -10,7 +10,7 @@ import { Meta, StoryObj } from "@storybook/react";
|
|
|
10
10
|
import { IframeData, IframeEmbedData } from "@ndla/types-embed";
|
|
11
11
|
import IframeEmbed from "./IframeEmbed";
|
|
12
12
|
import { ArticleWrapper } from "../Article";
|
|
13
|
-
import { OneColumn } from "../Layout";
|
|
13
|
+
import LayoutItem, { OneColumn } from "../Layout";
|
|
14
14
|
|
|
15
15
|
const embedData: IframeEmbedData = {
|
|
16
16
|
width: "708px",
|
|
@@ -29,11 +29,11 @@ const meta: Meta<typeof IframeEmbed> = {
|
|
|
29
29
|
(Story) => (
|
|
30
30
|
<OneColumn>
|
|
31
31
|
<ArticleWrapper modifier="clean">
|
|
32
|
-
<
|
|
32
|
+
<LayoutItem layout="center">
|
|
33
33
|
<section>
|
|
34
34
|
<Story />
|
|
35
35
|
</section>
|
|
36
|
-
</
|
|
36
|
+
</LayoutItem>
|
|
37
37
|
</ArticleWrapper>
|
|
38
38
|
</OneColumn>
|
|
39
39
|
),
|
|
@@ -13,7 +13,7 @@ import { ImageEmbedData } from "@ndla/types-embed";
|
|
|
13
13
|
import ImageEmbed from "./ImageEmbed";
|
|
14
14
|
import StoryFavoriteButton from "../../../../stories/StoryFavoriteButton";
|
|
15
15
|
import { ArticleWrapper } from "../Article";
|
|
16
|
-
import { OneColumn } from "../Layout";
|
|
16
|
+
import LayoutItem, { OneColumn } from "../Layout";
|
|
17
17
|
|
|
18
18
|
const embedData: ImageEmbedData = {
|
|
19
19
|
resource: "image",
|
|
@@ -96,11 +96,11 @@ const meta: Meta<typeof ImageEmbed> = {
|
|
|
96
96
|
(Story) => (
|
|
97
97
|
<OneColumn>
|
|
98
98
|
<ArticleWrapper modifier="clean">
|
|
99
|
-
<
|
|
99
|
+
<LayoutItem layout="center">
|
|
100
100
|
<section>
|
|
101
101
|
<Story />
|
|
102
102
|
</section>
|
|
103
|
-
</
|
|
103
|
+
</LayoutItem>
|
|
104
104
|
</ArticleWrapper>
|
|
105
105
|
</OneColumn>
|
|
106
106
|
),
|
|
@@ -10,7 +10,7 @@ import { Meta, StoryObj } from "@storybook/react";
|
|
|
10
10
|
import { RelatedContentMetaData } from "@ndla/types-embed";
|
|
11
11
|
import RelatedContentEmbed from "./RelatedContentEmbed";
|
|
12
12
|
import { ArticleWrapper } from "../Article";
|
|
13
|
-
import { OneColumn } from "../Layout";
|
|
13
|
+
import LayoutItem, { OneColumn } from "../Layout";
|
|
14
14
|
import RelatedArticleList from "../RelatedArticleList";
|
|
15
15
|
|
|
16
16
|
const filmResourceMeta: RelatedContentMetaData = {
|
|
@@ -369,11 +369,11 @@ const meta: Meta<typeof RelatedContentEmbed> = {
|
|
|
369
369
|
(Story) => (
|
|
370
370
|
<OneColumn>
|
|
371
371
|
<ArticleWrapper modifier="clean">
|
|
372
|
-
<
|
|
372
|
+
<LayoutItem layout="center">
|
|
373
373
|
<section>
|
|
374
374
|
<Story />
|
|
375
375
|
</section>
|
|
376
|
-
</
|
|
376
|
+
</LayoutItem>
|
|
377
377
|
</ArticleWrapper>
|
|
378
378
|
</OneColumn>
|
|
379
379
|
),
|
|
@@ -404,6 +404,17 @@ const linkEmbed2: RelatedContentMetaData = {
|
|
|
404
404
|
status: "success",
|
|
405
405
|
};
|
|
406
406
|
|
|
407
|
+
const linkEmbed3: RelatedContentMetaData = {
|
|
408
|
+
resource: "related-content",
|
|
409
|
+
embedData: {
|
|
410
|
+
resource: "related-content",
|
|
411
|
+
title: "Valg av tillitselev fra klassen",
|
|
412
|
+
url: "https://xn--elevrd-mua.no",
|
|
413
|
+
},
|
|
414
|
+
data: undefined,
|
|
415
|
+
status: "success",
|
|
416
|
+
};
|
|
417
|
+
|
|
407
418
|
export const RelatedContentStory: StoryObj<typeof RelatedContentEmbed> = {
|
|
408
419
|
render: () => (
|
|
409
420
|
<RelatedArticleList>
|
|
@@ -429,6 +440,7 @@ export const WithLinks: StoryObj<typeof RelatedContentEmbed> = {
|
|
|
429
440
|
<RelatedArticleList>
|
|
430
441
|
<RelatedContentEmbed embed={linkEmbed1} />
|
|
431
442
|
<RelatedContentEmbed embed={linkEmbed2} />
|
|
443
|
+
<RelatedContentEmbed embed={linkEmbed3} />
|
|
432
444
|
</RelatedArticleList>
|
|
433
445
|
),
|
|
434
446
|
};
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import punycode from "punycode/";
|
|
9
10
|
import { useTranslation } from "react-i18next";
|
|
10
11
|
import { RelatedContentMetaData } from "@ndla/types-embed";
|
|
11
12
|
import { contentTypeMapping } from "../model/ContentType";
|
|
@@ -53,7 +54,9 @@ const RelatedContentEmbed = ({ embed, isOembed, subject, ndlaFrontendDomain }: P
|
|
|
53
54
|
type={"external"}
|
|
54
55
|
linkInfo={`${t("related.linkInfo")} ${
|
|
55
56
|
// Get domain name only from url
|
|
56
|
-
|
|
57
|
+
punycode.toUnicode(
|
|
58
|
+
embedData.url.match(/^(?:https?:\/\/)?(?:[^@\n]+@)?(?:www\.)?([^:/\n]+)/im)?.[1] || embedData.url,
|
|
59
|
+
)
|
|
57
60
|
}`}
|
|
58
61
|
/>
|
|
59
62
|
);
|
|
@@ -15,7 +15,7 @@ import { ArticleWrapper } from "../Article";
|
|
|
15
15
|
import CopyParagraphButton from "../CopyParagraphButton";
|
|
16
16
|
import FactBox from "../FactBox";
|
|
17
17
|
import FramedContent from "../FramedContent";
|
|
18
|
-
import { OneColumn } from "../Layout";
|
|
18
|
+
import LayoutItem, { OneColumn } from "../Layout";
|
|
19
19
|
|
|
20
20
|
const embedData: UuDisclaimerEmbedData = {
|
|
21
21
|
resource: "uu-disclaimer",
|
|
@@ -31,11 +31,11 @@ const meta: Meta<typeof UuDisclaimerEmbed> = {
|
|
|
31
31
|
(Story) => (
|
|
32
32
|
<OneColumn>
|
|
33
33
|
<ArticleWrapper modifier="clean">
|
|
34
|
-
<
|
|
34
|
+
<LayoutItem layout="center">
|
|
35
35
|
<section>
|
|
36
36
|
<Story />
|
|
37
37
|
</section>
|
|
38
|
-
</
|
|
38
|
+
</LayoutItem>
|
|
39
39
|
</ArticleWrapper>
|
|
40
40
|
</OneColumn>
|
|
41
41
|
),
|
|
@@ -40,6 +40,10 @@ const CustomElementWrapper = styled.div`
|
|
|
40
40
|
margin: ${spacing.large} 0;
|
|
41
41
|
`;
|
|
42
42
|
|
|
43
|
+
const MessageWrapper = styled.div`
|
|
44
|
+
margin-top: ${spacing.xsmall};
|
|
45
|
+
`;
|
|
46
|
+
|
|
43
47
|
interface Props {
|
|
44
48
|
messages: {
|
|
45
49
|
title: string;
|
|
@@ -75,14 +79,14 @@ export const ErrorMessage = ({ children, messages, illustration, illustrationEle
|
|
|
75
79
|
</SafeLink>
|
|
76
80
|
)}
|
|
77
81
|
{messages.goToFrontPage && (
|
|
78
|
-
<
|
|
82
|
+
<MessageWrapper>
|
|
79
83
|
<SafeLink to="/">{messages.goToFrontPage}</SafeLink>
|
|
80
|
-
</
|
|
84
|
+
</MessageWrapper>
|
|
81
85
|
)}
|
|
82
86
|
{messages.logInFailed && (
|
|
83
|
-
<
|
|
87
|
+
<MessageWrapper>
|
|
84
88
|
<SafeLink to="/minndla">{messages.logInFailed}</SafeLink>
|
|
85
|
-
</
|
|
89
|
+
</MessageWrapper>
|
|
86
90
|
)}
|
|
87
91
|
{children}
|
|
88
92
|
</StyledErrorMessage>
|
package/src/Figure/Figure.tsx
CHANGED
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
// N.B These components is used to render static markup serverside
|
|
10
10
|
|
|
11
11
|
import { ComponentPropsWithRef, forwardRef, useMemo } from "react";
|
|
12
|
-
import { css } from "@emotion/react";
|
|
12
|
+
import { SerializedStyles, css } from "@emotion/react";
|
|
13
13
|
import styled from "@emotion/styled";
|
|
14
|
-
import { spacing } from "@ndla/core";
|
|
14
|
+
import { breakpoints, mq, spacing } from "@ndla/core";
|
|
15
15
|
|
|
16
16
|
const StyledFigure = styled.figure`
|
|
17
17
|
position: relative;
|
|
@@ -35,36 +35,114 @@ const StyledFigure = styled.figure`
|
|
|
35
35
|
}
|
|
36
36
|
`;
|
|
37
37
|
|
|
38
|
-
const
|
|
39
|
-
left:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
const floatSizes: Record<FigureType, SerializedStyles> = {
|
|
39
|
+
left: css`
|
|
40
|
+
margin-top: ${spacing.xsmall};
|
|
41
|
+
--float: left;
|
|
42
|
+
--width: 50%;
|
|
43
|
+
--width-desktop: 65%;
|
|
44
|
+
& {
|
|
45
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
46
|
+
padding-right: ${spacing.small};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
`,
|
|
50
|
+
right: css`
|
|
51
|
+
margin-top: ${spacing.xsmall};
|
|
52
|
+
--float: right;
|
|
53
|
+
--width: 50%;
|
|
54
|
+
--width-desktop: 65%;
|
|
55
|
+
& {
|
|
56
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
57
|
+
padding-left: ${spacing.small};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
`,
|
|
61
|
+
"small-left": css`
|
|
62
|
+
margin-top: ${spacing.xsmall};
|
|
63
|
+
--float: left;
|
|
64
|
+
--width: 25%;
|
|
65
|
+
--width-desktop: 50%;
|
|
66
|
+
& {
|
|
67
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
68
|
+
padding-right: ${spacing.small};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
`,
|
|
72
|
+
"small-right": css`
|
|
73
|
+
margin-top: ${spacing.xsmall};
|
|
74
|
+
--float: right;
|
|
75
|
+
--width: 25%;
|
|
76
|
+
--width-desktop: 50%;
|
|
77
|
+
& {
|
|
78
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
79
|
+
padding-left: ${spacing.small};
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
`,
|
|
83
|
+
"xsmall-left": css`
|
|
84
|
+
--float: left;
|
|
85
|
+
--width: 25%;
|
|
86
|
+
& {
|
|
87
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
88
|
+
padding-right: ${spacing.small};
|
|
89
|
+
margin: ${spacing.xsmall} 0 ${spacing.medium};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
`,
|
|
93
|
+
"xsmall-right": css`
|
|
94
|
+
--float: right;
|
|
95
|
+
--width: 25%;
|
|
96
|
+
& {
|
|
97
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
98
|
+
padding-left: ${spacing.small};
|
|
99
|
+
margin: ${spacing.xsmall} 0 ${spacing.normal} ${spacing.xsmall};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
`,
|
|
103
|
+
full: css`
|
|
104
|
+
margin-top: ${spacing.xsmall};
|
|
105
|
+
`,
|
|
106
|
+
"full-column": css`
|
|
107
|
+
left: auto !important;
|
|
108
|
+
right: auto !important;
|
|
109
|
+
width: auto !important;
|
|
110
|
+
padding-left: 0;
|
|
111
|
+
padding-right: 0;
|
|
112
|
+
padding-bottom: ${spacing.large};
|
|
113
|
+
margin-bottom: 0;
|
|
114
|
+
`,
|
|
115
|
+
};
|
|
47
116
|
|
|
48
|
-
const
|
|
49
|
-
|
|
117
|
+
const floatStyle = css`
|
|
118
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
119
|
+
float: var(--float);
|
|
120
|
+
clear: var(--float);
|
|
121
|
+
width: var(--width) !important;
|
|
122
|
+
z-index: 1;
|
|
123
|
+
left: auto !important;
|
|
124
|
+
padding: 0;
|
|
125
|
+
}
|
|
126
|
+
${mq.range({ from: breakpoints.desktop })} {
|
|
127
|
+
width: var(--width-desktop, var(--width)) !important;
|
|
128
|
+
}
|
|
50
129
|
`;
|
|
51
130
|
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
const Figure = forwardRef<HTMLElement, Props>(({ children, type = "full", className, ...rest }, ref) => {
|
|
55
|
-
const floatClass = type === "full-column" ? undefined : `u-float-${type}`;
|
|
56
|
-
|
|
131
|
+
const Figure = forwardRef<HTMLElement, Props>(({ children, type = "full", ...rest }, ref) => {
|
|
57
132
|
const styles = useMemo(() => {
|
|
58
133
|
const styles = [];
|
|
59
|
-
|
|
60
|
-
if (
|
|
134
|
+
const floatCss = floatSizes[type];
|
|
135
|
+
if (type !== "full-column" && type !== "full") {
|
|
136
|
+
styles.push(floatStyle);
|
|
137
|
+
}
|
|
138
|
+
if (floatCss) {
|
|
139
|
+
styles.push(floatCss);
|
|
140
|
+
}
|
|
61
141
|
return styles;
|
|
62
|
-
}, [
|
|
63
|
-
|
|
64
|
-
const classes = floatClass ? `${floatClass} ${className ?? ""}` : className;
|
|
142
|
+
}, [type]);
|
|
65
143
|
|
|
66
144
|
return (
|
|
67
|
-
<StyledFigure data-sizetype={type} css={styles}
|
|
145
|
+
<StyledFigure data-sizetype={type} css={styles} {...rest} ref={ref}>
|
|
68
146
|
{children}
|
|
69
147
|
</StyledFigure>
|
|
70
148
|
);
|
|
@@ -65,7 +65,7 @@ interface Props {
|
|
|
65
65
|
const KeyFigure = ({ image, title, subtitle }: Props) => {
|
|
66
66
|
return (
|
|
67
67
|
<ContentWrapper>
|
|
68
|
-
<StyledImage src={image?.src} width={150} height={150} alt={image?.alt} />
|
|
68
|
+
<StyledImage src={`${image?.src}?width=150`} width={150} height={150} alt={image?.alt} />
|
|
69
69
|
<TitleWrapper>{parse(title)}</TitleWrapper>
|
|
70
70
|
<SubTitleWrapper>{parse(subtitle)}</SubTitleWrapper>
|
|
71
71
|
</ContentWrapper>
|
|
@@ -7,25 +7,42 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { HTMLAttributes, ReactNode, useMemo } from "react";
|
|
10
|
+
import { css } from "@emotion/react";
|
|
11
|
+
import { mq, breakpoints } from "@ndla/core";
|
|
10
12
|
|
|
11
13
|
interface Props extends HTMLAttributes<HTMLElement> {
|
|
12
14
|
children?: ReactNode;
|
|
13
15
|
layout?: "extend" | "center";
|
|
14
16
|
}
|
|
15
17
|
|
|
18
|
+
const centerCss = css`
|
|
19
|
+
position: relative !important;
|
|
20
|
+
width: 83.333%;
|
|
21
|
+
right: auto !important;
|
|
22
|
+
left: 8.333%;
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
const extendCss = css`
|
|
26
|
+
${mq.range({ from: breakpoints.tablet })} {
|
|
27
|
+
position: relative !important;
|
|
28
|
+
width: 83.333%;
|
|
29
|
+
right: auto !important;
|
|
30
|
+
left: 8.333%;
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
|
|
16
34
|
export const LayoutItem = ({ children, layout, ...rest }: Props) => {
|
|
17
|
-
const
|
|
35
|
+
const style = useMemo(() => {
|
|
18
36
|
if (layout === "extend") {
|
|
19
|
-
return
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return "u-10/12 u-push-1/12";
|
|
37
|
+
return extendCss;
|
|
38
|
+
} else if (layout === "center") {
|
|
39
|
+
return centerCss;
|
|
23
40
|
}
|
|
24
41
|
return undefined;
|
|
25
42
|
}, [layout]);
|
|
26
43
|
|
|
27
44
|
return (
|
|
28
|
-
<section
|
|
45
|
+
<section css={style} {...rest}>
|
|
29
46
|
{children}
|
|
30
47
|
</section>
|
|
31
48
|
);
|
package/src/Layout/index.ts
CHANGED
|
@@ -82,7 +82,7 @@ export const WithNumbersAndLetters: StoryFn = () => (
|
|
|
82
82
|
);
|
|
83
83
|
|
|
84
84
|
export const StartingAtFive: StoryFn = () => (
|
|
85
|
-
<OrderedList start={5} data-type="letters"
|
|
85
|
+
<OrderedList start={5} data-type="letters">
|
|
86
86
|
<li>Listepunkt 1</li>
|
|
87
87
|
<li>Listepunkt 2</li>
|
|
88
88
|
<li>
|
|
@@ -97,7 +97,7 @@ export const StartingAtFive: StoryFn = () => (
|
|
|
97
97
|
<li>Listepunkt 2</li>
|
|
98
98
|
<li>
|
|
99
99
|
Listepunkt 3
|
|
100
|
-
<OrderedList
|
|
100
|
+
<OrderedList start={5}>
|
|
101
101
|
<li>Listepunkt 1</li>
|
|
102
102
|
<li>Listepunkt 2</li>
|
|
103
103
|
<li>Listepunkt 3</li>
|