@ndla/ui 56.0.52-alpha.0 → 56.0.54-alpha.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.
@@ -10,8 +10,8 @@ import { Meta, StoryFn } from "@storybook/react";
10
10
  import { PageContent } from "@ndla/primitives";
11
11
  import { ArticleContent, ArticleWrapper } from "@ndla/ui";
12
12
  import { Grid } from "./Grid";
13
- import { BlogPostStory } from "../BlogPost/BlogPost.stories";
14
13
  import { Plain } from "../KeyFigure/KeyFigure.stories";
14
+ import { Default as PitchStory } from "../Pitch/Pitch.stories";
15
15
 
16
16
  export default {
17
17
  title: "Components/Grid",
@@ -59,17 +59,15 @@ export const GridKeyPerformanceStory: StoryFn<typeof Grid> = ({ ...args }) => {
59
59
  return <Grid {...args}>{items}</Grid>;
60
60
  };
61
61
 
62
- export const GridBlogPostStory: StoryFn<typeof Grid> = ({ ...args }) => {
62
+ export const GridPitchStory: StoryFn<typeof Grid> = ({ ...args }) => {
63
63
  const columns = args.columns === "2x2" ? 4 : parseInt(args.columns);
64
64
  const items = new Array(columns).fill(
65
65
  <div data-type="grid-cell" data-parallax-cell="false">
66
- <BlogPostStory
67
- metaImage={BlogPostStory.args?.metaImage!}
68
- title={BlogPostStory.args?.title!}
69
- size={"normal"}
70
- headingLevel={BlogPostStory.args?.headingLevel}
71
- url={BlogPostStory.args?.url!}
72
- author={BlogPostStory.args?.author}
66
+ <PitchStory
67
+ metaImage={PitchStory.args?.metaImage!}
68
+ title={PitchStory.args?.title!}
69
+ url={PitchStory.args?.url!}
70
+ description={PitchStory.args?.description}
73
71
  />
74
72
  </div>,
75
73
  );
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Copyright (c) 2024-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 { Meta, StoryFn } from "@storybook/react";
10
+ import { PageContent } from "@ndla/primitives";
11
+ import { Pitch } from "./Pitch";
12
+ import { ArticleContent, ArticleWrapper } from "../Article";
13
+ import { Grid } from "../Grid";
14
+
15
+ export default {
16
+ title: "Components/Pitch",
17
+ component: Pitch,
18
+ tags: ["autodocs"],
19
+ args: {
20
+ title: "Min bloggpost",
21
+ description:
22
+ "Vil du øve på spansk? Kunne du tenke deg hjelp til naturfag? Drømmer du om en prat med Mandela? Lag din egen praterobot!",
23
+ url: "#",
24
+ metaImage: {
25
+ alt: "Yonghetempelet i Beijing. Foto.",
26
+ url: "https://api.test.ndla.no/image-api/raw/id//62870",
27
+ },
28
+ },
29
+ decorators: [
30
+ (Story) => (
31
+ <PageContent variant="page" asChild>
32
+ <ArticleWrapper>
33
+ <ArticleContent>
34
+ <Story />
35
+ </ArticleContent>
36
+ </ArticleWrapper>
37
+ </PageContent>
38
+ ),
39
+ ],
40
+ } as Meta<typeof Pitch>;
41
+
42
+ export const Default: StoryFn<typeof Pitch> = ({ ...args }) => {
43
+ return (
44
+ <Grid columns="2" background="transparent">
45
+ <Pitch {...args} />
46
+ <Pitch {...args} />
47
+ </Grid>
48
+ );
49
+ };
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Copyright (c) 2024-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 parse from "html-react-parser";
10
+ import { CardHeading, CardImage, CardRoot, Text } from "@ndla/primitives";
11
+ import { SafeLink } from "@ndla/safelink";
12
+ import { styled } from "@ndla/styled-system/jsx";
13
+ import { linkOverlay } from "@ndla/styled-system/patterns";
14
+ import { getPossiblyRelativeUrl } from "../utils/relativeUrl";
15
+
16
+ export interface Props {
17
+ title: string;
18
+ url: string;
19
+ description?: string;
20
+ metaImage: {
21
+ url: string;
22
+ alt: string;
23
+ };
24
+ path?: string;
25
+ }
26
+
27
+ const StyledCardHeading = styled(CardHeading, {
28
+ base: {
29
+ paddingBlockStart: "medium",
30
+ },
31
+ });
32
+
33
+ const StyledText = styled(Text, {
34
+ base: {
35
+ paddingBlockEnd: "medium",
36
+ },
37
+ });
38
+
39
+ const StyledCardRoot = styled(CardRoot, {
40
+ base: {
41
+ border: "0",
42
+ display: "flex",
43
+ flexDirection: "column",
44
+ gap: "small",
45
+ },
46
+ });
47
+
48
+ const StyledCardImage = styled(CardImage, {
49
+ base: {
50
+ aspectRatio: "16/9",
51
+ height: "unset",
52
+ },
53
+ });
54
+
55
+ export const Pitch = ({ title, url, metaImage, path, description }: Props) => {
56
+ const href = getPossiblyRelativeUrl(url, path);
57
+
58
+ return (
59
+ <StyledCardRoot variant="subtle" data-embed-type="pitch" asChild consumeCss>
60
+ <div>
61
+ <StyledCardHeading textStyle="heading.small" asChild consumeCss>
62
+ <SafeLink to={href} unstyled css={linkOverlay.raw()}>
63
+ {parse(title)}
64
+ </SafeLink>
65
+ </StyledCardHeading>
66
+ {!!description && (
67
+ <StyledText textStyle="body.xlarge" asChild consumeCss>
68
+ <div>{parse(description)}</div>
69
+ </StyledText>
70
+ )}
71
+ <StyledCardImage
72
+ variant="rounded"
73
+ src={metaImage.url}
74
+ alt={metaImage.alt}
75
+ sizes="180px"
76
+ fallbackWidth={300}
77
+ width={550}
78
+ height={310}
79
+ />
80
+ </div>
81
+ </StyledCardRoot>
82
+ );
83
+ };
@@ -6,4 +6,4 @@
6
6
  *
7
7
  */
8
8
 
9
- export { default as BlogPostV2 } from "./BlogPost";
9
+ export { Pitch } from "./Pitch";
package/src/index.ts CHANGED
@@ -133,7 +133,7 @@ export {
133
133
  TagSelectorInput,
134
134
  } from "./TagSelector/TagSelector";
135
135
 
136
- export { BlogPostV2 } from "./BlogPost";
136
+ export { Pitch } from "./Pitch";
137
137
  export { KeyFigure } from "./KeyFigure";
138
138
  export { ContactBlock, contactBlockBackgrounds } from "./ContactBlock";
139
139
  export type { ContactBlockBackground } from "./ContactBlock";
@@ -233,7 +233,7 @@ const messages = {
233
233
  "What will it mean to work exploratory? How can you learn better? What is needed in order to make group work function? In the toolbox both students and teach find resources that are current for every subject, and that support learning work and development of knowledge, skills and understanding.",
234
234
  },
235
235
  meta: {
236
- description: "Norwegian Digital Learning Arena, Open Educational Resources",
236
+ description: "Norwegian Digital Learning Arena, Open Educational Resources for upper secondary education.",
237
237
  keywords: "open educational resources,teaching,learning",
238
238
  },
239
239
  masthead: {
@@ -233,7 +233,8 @@ const messages = {
233
233
  "Hva vil det si å arbeide utforskende? Hvordan kan du lære bedre? Hva skal til for å få gruppearbeid til å fungere? I Verktøykassa finner både elever og lærere ressurser som er aktuelle for alle fag, og som støtter opp under læringsarbeid og utvikling av kunnskap, ferdigheter og forståelse.",
234
234
  },
235
235
  meta: {
236
- description: "Kvalitetssikrede og fritt tilgjengelige nettbaserte læremidler for videregående opplæring",
236
+ description:
237
+ "Åpne og fritt tilgjengelige ressurser for videregående opplæring. Utviklet og oppdatert i samarbeid med dyktige lærere og elever.",
237
238
  keywords: "læremiddel,fag,skole,videregående,lærling,pensum,fagstoff",
238
239
  },
239
240
  masthead: {
@@ -233,7 +233,8 @@ const messages = {
233
233
  "Kva vil det seie å arbeide utforskande? Korleis kan du lære betre? Kva skal til for å få gruppearbeid til å fungere? I Verktøykassa finn både elevar og lærerar ressursar som er aktuelle for alle fag, og som støtter opp under læringsarbeid og utvikling av kunnskap, ferdigheter og forståing.",
234
234
  },
235
235
  meta: {
236
- description: "Kvalitetssikra og fritt tilgjengelege nettbaserte læremiddel for vidaregåande opplæring",
236
+ description:
237
+ "Opne og fritt tilgjengelege ressursar for vidaregåande opplæring. Utvikla og oppdaterte i samarbeid med dyktige lærarar og elevar.",
237
238
  keywords: "læremiddel,fag,skole,skule,vidaregåande,lærling,pensum,fagstoff, ",
238
239
  },
239
240
  masthead: {
@@ -1,129 +0,0 @@
1
- /**
2
- * Copyright (c) 2023-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 parse from "html-react-parser";
10
- import { useTranslation } from "react-i18next";
11
- import { Heading } from "@ndla/primitives";
12
- import { SafeLink } from "@ndla/safelink";
13
- import { styled } from "@ndla/styled-system/jsx";
14
- import { getPossiblyRelativeUrl } from "../utils/relativeUrl";
15
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
16
- const Container = styled(SafeLink, {
17
- base: {
18
- display: "flex",
19
- flexDirection: "column",
20
- color: "text.default",
21
- backgroundColor: "background.default",
22
- gap: "medium",
23
- border: "1px solid",
24
- borderColor: "stroke.subtle",
25
- borderRadius: "xsmall",
26
- transitionDuration: "fast",
27
- transitionProperty: "background-color, border-color, max-width",
28
- transitionTimingFunction: "default",
29
- height: "100%",
30
- "&:hover, &:focus-visible": {
31
- borderColor: "stroke.hover",
32
- backgroundColor: "surface.actionSubtle.hover",
33
- "& h1, h2, h3, h4, h5, h6": {
34
- textDecoration: "underline"
35
- }
36
- }
37
- },
38
- defaultVariants: {
39
- size: "normal"
40
- },
41
- variants: {
42
- // TODO: Reconsider these sizes. Maybe they should match up with surface?
43
- size: {
44
- normal: {
45
- paddingBlock: "medium",
46
- paddingInline: "medium",
47
- tabletWide: {
48
- maxWidth: "350px"
49
- }
50
- },
51
- large: {
52
- paddingBlock: "xlarge",
53
- paddingInline: "xxlarge",
54
- tabletWide: {
55
- maxWidth: "532px"
56
- }
57
- }
58
- }
59
- }
60
- },
61
- // TODO: Reconsider this once we handle SafeLink
62
- {
63
- baseComponent: true
64
- });
65
- const AuthorContainer = styled("div", {
66
- base: {
67
- display: "flex",
68
- alignItems: "center",
69
- gap: "xsmall",
70
- textTransform: "uppercase",
71
- textStyle: "body.large"
72
- }
73
- });
74
- const StyledImg = styled("img", {
75
- base: {
76
- borderRadius: "xsmall",
77
- flex: "1",
78
- objectFit: "cover",
79
- width: "100%",
80
- height: "100%",
81
- border: "0"
82
- }
83
- });
84
- const StyledHeading = styled(Heading, {
85
- base: {
86
- display: "inline-block",
87
- width: "fit-content"
88
- }
89
- });
90
- const BlogPost = _ref => {
91
- let {
92
- title,
93
- author,
94
- url,
95
- metaImage,
96
- headingLevel: Heading = "h3",
97
- size = "normal",
98
- path
99
- } = _ref;
100
- const {
101
- t
102
- } = useTranslation();
103
- const href = getPossiblyRelativeUrl(url, path);
104
- const imageWidth = size === "large" ? 532 : 350;
105
- return /*#__PURE__*/_jsxs(Container, {
106
- "data-size": size,
107
- to: href,
108
- size: size,
109
- "data-embed-type": "blog-post",
110
- children: [/*#__PURE__*/_jsx(StyledHeading, {
111
- className: "blog-title",
112
- asChild: true,
113
- consumeCss: true,
114
- textStyle: "title.large",
115
- children: /*#__PURE__*/_jsx(Heading, {
116
- children: parse(title)
117
- })
118
- }), /*#__PURE__*/_jsx(StyledImg, {
119
- src: `${metaImage.url}?width=${imageWidth}`,
120
- alt: metaImage.alt
121
- }), !!author && /*#__PURE__*/_jsx(AuthorContainer, {
122
- "aria-label": t("article.writtenBy", {
123
- authors: author
124
- }),
125
- children: author
126
- })]
127
- });
128
- };
129
- export default BlogPost;
@@ -1,22 +0,0 @@
1
- /**
2
- * Copyright (c) 2023-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
- import { HeadingLevel } from "../types";
9
- export interface Props {
10
- title: string;
11
- author?: string;
12
- url: string;
13
- headingLevel?: HeadingLevel;
14
- size?: "normal" | "large";
15
- metaImage: {
16
- url: string;
17
- alt: string;
18
- };
19
- path?: string;
20
- }
21
- declare const BlogPost: ({ title, author, url, metaImage, headingLevel: Heading, size, path }: Props) => import("react/jsx-runtime").JSX.Element;
22
- export default BlogPost;
@@ -1,136 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
- var _htmlReactParser = _interopRequireDefault(require("html-react-parser"));
8
- var _reactI18next = require("react-i18next");
9
- var _primitives = require("@ndla/primitives");
10
- var _safelink = require("@ndla/safelink");
11
- var _jsx2 = require("@ndla/styled-system/jsx");
12
- var _relativeUrl = require("../utils/relativeUrl");
13
- var _jsxRuntime = require("react/jsx-runtime");
14
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
- /**
16
- * Copyright (c) 2023-present, NDLA.
17
- *
18
- * This source code is licensed under the GPLv3 license found in the
19
- * LICENSE file in the root directory of this source tree.
20
- *
21
- */
22
-
23
- const Container = (0, _jsx2.styled)(_safelink.SafeLink, {
24
- base: {
25
- display: "flex",
26
- flexDirection: "column",
27
- color: "text.default",
28
- backgroundColor: "background.default",
29
- gap: "medium",
30
- border: "1px solid",
31
- borderColor: "stroke.subtle",
32
- borderRadius: "xsmall",
33
- transitionDuration: "fast",
34
- transitionProperty: "background-color, border-color, max-width",
35
- transitionTimingFunction: "default",
36
- height: "100%",
37
- "&:hover, &:focus-visible": {
38
- borderColor: "stroke.hover",
39
- backgroundColor: "surface.actionSubtle.hover",
40
- "& h1, h2, h3, h4, h5, h6": {
41
- textDecoration: "underline"
42
- }
43
- }
44
- },
45
- defaultVariants: {
46
- size: "normal"
47
- },
48
- variants: {
49
- // TODO: Reconsider these sizes. Maybe they should match up with surface?
50
- size: {
51
- normal: {
52
- paddingBlock: "medium",
53
- paddingInline: "medium",
54
- tabletWide: {
55
- maxWidth: "350px"
56
- }
57
- },
58
- large: {
59
- paddingBlock: "xlarge",
60
- paddingInline: "xxlarge",
61
- tabletWide: {
62
- maxWidth: "532px"
63
- }
64
- }
65
- }
66
- }
67
- },
68
- // TODO: Reconsider this once we handle SafeLink
69
- {
70
- baseComponent: true
71
- });
72
- const AuthorContainer = (0, _jsx2.styled)("div", {
73
- base: {
74
- display: "flex",
75
- alignItems: "center",
76
- gap: "xsmall",
77
- textTransform: "uppercase",
78
- textStyle: "body.large"
79
- }
80
- });
81
- const StyledImg = (0, _jsx2.styled)("img", {
82
- base: {
83
- borderRadius: "xsmall",
84
- flex: "1",
85
- objectFit: "cover",
86
- width: "100%",
87
- height: "100%",
88
- border: "0"
89
- }
90
- });
91
- const StyledHeading = (0, _jsx2.styled)(_primitives.Heading, {
92
- base: {
93
- display: "inline-block",
94
- width: "fit-content"
95
- }
96
- });
97
- const BlogPost = _ref => {
98
- let {
99
- title,
100
- author,
101
- url,
102
- metaImage,
103
- headingLevel: Heading = "h3",
104
- size = "normal",
105
- path
106
- } = _ref;
107
- const {
108
- t
109
- } = (0, _reactI18next.useTranslation)();
110
- const href = (0, _relativeUrl.getPossiblyRelativeUrl)(url, path);
111
- const imageWidth = size === "large" ? 532 : 350;
112
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(Container, {
113
- "data-size": size,
114
- to: href,
115
- size: size,
116
- "data-embed-type": "blog-post",
117
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(StyledHeading, {
118
- className: "blog-title",
119
- asChild: true,
120
- consumeCss: true,
121
- textStyle: "title.large",
122
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Heading, {
123
- children: (0, _htmlReactParser.default)(title)
124
- })
125
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(StyledImg, {
126
- src: `${metaImage.url}?width=${imageWidth}`,
127
- alt: metaImage.alt
128
- }), !!author && /*#__PURE__*/(0, _jsxRuntime.jsx)(AuthorContainer, {
129
- "aria-label": t("article.writtenBy", {
130
- authors: author
131
- }),
132
- children: author
133
- })]
134
- });
135
- };
136
- var _default = exports.default = BlogPost;
@@ -1,13 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- Object.defineProperty(exports, "BlogPostV2", {
7
- enumerable: true,
8
- get: function () {
9
- return _BlogPost.default;
10
- }
11
- });
12
- var _BlogPost = _interopRequireDefault(require("./BlogPost"));
13
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -1,36 +0,0 @@
1
- /**
2
- * Copyright (c) 2023-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 { Meta, StoryFn } from "@storybook/react";
10
- import BlogPost, { Props } from "./BlogPost";
11
-
12
- const args: Props = {
13
- title: "Min bloggpost",
14
- author: "Ola Nordmann",
15
- url: "#",
16
- headingLevel: "h3",
17
- size: "large",
18
- metaImage: {
19
- alt: "Yonghetempelet i Beijing. Foto.",
20
- url: "https://api.test.ndla.no/image-api/raw/id//62870",
21
- },
22
- };
23
-
24
- export default {
25
- title: "Components/Blog Post",
26
- component: BlogPost,
27
- tags: ["autodocs"],
28
- args: args,
29
- } as Meta<typeof BlogPost>;
30
-
31
- export const BlogPostStory: StoryFn<typeof BlogPost> = ({ ...args }) => {
32
- return <BlogPost {...args} />;
33
- };
34
-
35
- BlogPostStory.args = args;
36
- BlogPostStory.storyName = "BlogPost";
@@ -1,124 +0,0 @@
1
- /**
2
- * Copyright (c) 2023-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 parse from "html-react-parser";
10
- import { useTranslation } from "react-i18next";
11
- import { Heading } from "@ndla/primitives";
12
- import { SafeLink } from "@ndla/safelink";
13
- import { styled } from "@ndla/styled-system/jsx";
14
- import { HeadingLevel } from "../types";
15
- import { getPossiblyRelativeUrl } from "../utils/relativeUrl";
16
-
17
- export interface Props {
18
- title: string;
19
- author?: string;
20
- url: string;
21
- headingLevel?: HeadingLevel;
22
- size?: "normal" | "large";
23
- metaImage: {
24
- url: string;
25
- alt: string;
26
- };
27
- path?: string;
28
- }
29
-
30
- const Container = styled(
31
- SafeLink,
32
- {
33
- base: {
34
- display: "flex",
35
- flexDirection: "column",
36
- color: "text.default",
37
- backgroundColor: "background.default",
38
- gap: "medium",
39
- border: "1px solid",
40
- borderColor: "stroke.subtle",
41
- borderRadius: "xsmall",
42
- transitionDuration: "fast",
43
- transitionProperty: "background-color, border-color, max-width",
44
- transitionTimingFunction: "default",
45
- height: "100%",
46
- "&:hover, &:focus-visible": {
47
- borderColor: "stroke.hover",
48
- backgroundColor: "surface.actionSubtle.hover",
49
- "& h1, h2, h3, h4, h5, h6": {
50
- textDecoration: "underline",
51
- },
52
- },
53
- },
54
- defaultVariants: {
55
- size: "normal",
56
- },
57
- variants: {
58
- // TODO: Reconsider these sizes. Maybe they should match up with surface?
59
- size: {
60
- normal: {
61
- paddingBlock: "medium",
62
- paddingInline: "medium",
63
- tabletWide: {
64
- maxWidth: "350px",
65
- },
66
- },
67
- large: {
68
- paddingBlock: "xlarge",
69
- paddingInline: "xxlarge",
70
- tabletWide: {
71
- maxWidth: "532px",
72
- },
73
- },
74
- },
75
- },
76
- },
77
- // TODO: Reconsider this once we handle SafeLink
78
- { baseComponent: true },
79
- );
80
-
81
- const AuthorContainer = styled("div", {
82
- base: {
83
- display: "flex",
84
- alignItems: "center",
85
- gap: "xsmall",
86
- textTransform: "uppercase",
87
- textStyle: "body.large",
88
- },
89
- });
90
-
91
- const StyledImg = styled("img", {
92
- base: {
93
- borderRadius: "xsmall",
94
- flex: "1",
95
- objectFit: "cover",
96
- width: "100%",
97
- height: "100%",
98
- border: "0",
99
- },
100
- });
101
-
102
- const StyledHeading = styled(Heading, {
103
- base: {
104
- display: "inline-block",
105
- width: "fit-content",
106
- },
107
- });
108
-
109
- const BlogPost = ({ title, author, url, metaImage, headingLevel: Heading = "h3", size = "normal", path }: Props) => {
110
- const { t } = useTranslation();
111
- const href = getPossiblyRelativeUrl(url, path);
112
- const imageWidth = size === "large" ? 532 : 350;
113
- return (
114
- <Container data-size={size} to={href} size={size} data-embed-type="blog-post">
115
- <StyledHeading className="blog-title" asChild consumeCss textStyle="title.large">
116
- <Heading>{parse(title)}</Heading>
117
- </StyledHeading>
118
- <StyledImg src={`${metaImage.url}?width=${imageWidth}`} alt={metaImage.alt} />
119
- {!!author && <AuthorContainer aria-label={t("article.writtenBy", { authors: author })}>{author}</AuthorContainer>}
120
- </Container>
121
- );
122
- };
123
-
124
- export default BlogPost;