@ndla/ui 56.0.3-alpha.0 → 56.0.5-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.
Files changed (104) hide show
  1. package/dist/panda.buildinfo.json +35 -8
  2. package/dist/styles.css +148 -29
  3. package/es/Article/Article.js +1 -5
  4. package/es/Article/ArticleContent.js +27 -0
  5. package/es/Article/index.js +2 -1
  6. package/es/Breadcrumb/Breadcrumb.js +2 -3
  7. package/es/Breadcrumb/BreadcrumbItem.js +1 -1
  8. package/es/Breadcrumb/HomeBreadcrumb.js +2 -2
  9. package/es/Embed/ImageEmbed.js +2 -1
  10. package/es/ErrorMessage/ErrorMessage.js +2 -0
  11. package/es/FileList/File.js +78 -23
  12. package/es/FileList/FileList.js +32 -37
  13. package/es/FileList/PdfFile.js +17 -16
  14. package/es/FileList/index.js +3 -5
  15. package/es/Grid/Grid.js +69 -48
  16. package/es/Grid/GridParallaxItem.js +32 -0
  17. package/es/Grid/index.js +2 -1
  18. package/es/KeyFigure/KeyFigure.js +28 -33
  19. package/es/LinkBlock/LinkBlockSection.js +1 -0
  20. package/es/RelatedArticleList/RelatedArticleList.js +1 -1
  21. package/es/index.js +1 -4
  22. package/es/styles.css +148 -29
  23. package/lib/Article/Article.d.ts +0 -1
  24. package/lib/Article/Article.js +3 -7
  25. package/lib/Article/ArticleContent.d.ts +11 -0
  26. package/lib/Article/ArticleContent.js +33 -0
  27. package/lib/Article/index.d.ts +2 -1
  28. package/lib/Article/index.js +2 -1
  29. package/lib/Breadcrumb/Breadcrumb.js +2 -3
  30. package/lib/Breadcrumb/BreadcrumbItem.js +1 -1
  31. package/lib/Breadcrumb/HomeBreadcrumb.js +1 -1
  32. package/lib/Embed/ImageEmbed.js +2 -1
  33. package/lib/ErrorMessage/ErrorMessage.js +2 -0
  34. package/lib/FileList/File.d.ts +5 -3
  35. package/lib/FileList/File.js +78 -23
  36. package/lib/FileList/FileList.d.ts +6 -6
  37. package/lib/FileList/FileList.js +35 -38
  38. package/lib/FileList/PdfFile.d.ts +2 -2
  39. package/lib/FileList/PdfFile.js +17 -15
  40. package/lib/FileList/index.d.ts +3 -5
  41. package/lib/FileList/index.js +19 -18
  42. package/lib/Grid/Grid.d.ts +4 -7
  43. package/lib/Grid/Grid.js +71 -49
  44. package/lib/Grid/GridParallaxItem.d.ts +9 -0
  45. package/lib/Grid/GridParallaxItem.js +39 -0
  46. package/lib/Grid/index.d.ts +2 -1
  47. package/lib/Grid/index.js +4 -5
  48. package/lib/KeyFigure/KeyFigure.js +30 -33
  49. package/lib/LinkBlock/LinkBlockSection.js +1 -0
  50. package/lib/RelatedArticleList/RelatedArticleList.js +1 -1
  51. package/lib/index.d.ts +1 -4
  52. package/lib/index.js +9 -24
  53. package/lib/styles.css +148 -29
  54. package/package.json +7 -7
  55. package/src/Article/Article.tsx +1 -6
  56. package/src/Article/ArticleContent.tsx +21 -0
  57. package/src/Article/index.ts +2 -1
  58. package/src/Breadcrumb/Breadcrumb.tsx +1 -2
  59. package/src/Breadcrumb/BreadcrumbItem.tsx +1 -1
  60. package/src/Breadcrumb/HomeBreadcrumb.tsx +2 -2
  61. package/src/ContentTypeBadge/ContentTypeBadge.stories.tsx +8 -7
  62. package/src/Embed/ImageEmbed.stories.tsx +1 -3
  63. package/src/Embed/ImageEmbed.tsx +3 -2
  64. package/src/ErrorMessage/ErrorMessage.tsx +2 -0
  65. package/src/FileList/File.tsx +63 -28
  66. package/src/FileList/FileList.stories.tsx +121 -12
  67. package/src/FileList/FileList.tsx +31 -37
  68. package/src/FileList/PdfFile.tsx +9 -9
  69. package/src/FileList/index.ts +3 -7
  70. package/src/Grid/Grid.stories.tsx +30 -31
  71. package/src/Grid/Grid.tsx +57 -85
  72. package/src/Grid/GridParallaxItem.tsx +26 -0
  73. package/src/Grid/index.ts +3 -1
  74. package/src/KeyFigure/KeyFigure.stories.tsx +18 -11
  75. package/src/KeyFigure/KeyFigure.tsx +33 -47
  76. package/src/LinkBlock/LinkBlockSection.tsx +1 -1
  77. package/src/RelatedArticleList/RelatedArticleList.tsx +1 -1
  78. package/src/index.ts +1 -7
  79. package/es/FileList/Format.js +0 -93
  80. package/es/Footer/FooterBlock.js +0 -17
  81. package/es/Footer/index.js +0 -9
  82. package/es/Messages/MessageBox.js +0 -79
  83. package/es/Messages/index.js +0 -10
  84. package/es/utils/resourceTypeColor.js +0 -46
  85. package/lib/FileList/Format.d.ts +0 -16
  86. package/lib/FileList/Format.js +0 -98
  87. package/lib/Footer/FooterBlock.d.ts +0 -13
  88. package/lib/Footer/FooterBlock.js +0 -24
  89. package/lib/Footer/index.d.ts +0 -8
  90. package/lib/Footer/index.js +0 -12
  91. package/lib/Messages/MessageBox.d.ts +0 -23
  92. package/lib/Messages/MessageBox.js +0 -87
  93. package/lib/Messages/index.d.ts +0 -9
  94. package/lib/Messages/index.js +0 -13
  95. package/lib/utils/resourceTypeColor.d.ts +0 -9
  96. package/lib/utils/resourceTypeColor.js +0 -54
  97. package/src/FileList/Format.tsx +0 -83
  98. package/src/Footer/Footer.stories.tsx +0 -35
  99. package/src/Footer/FooterBlock.tsx +0 -30
  100. package/src/Footer/index.ts +0 -9
  101. package/src/Messages/MessageBox.stories.tsx +0 -95
  102. package/src/Messages/MessageBox.tsx +0 -126
  103. package/src/Messages/index.ts +0 -11
  104. package/src/utils/resourceTypeColor.tsx +0 -46
@@ -6,17 +6,23 @@
6
6
  *
7
7
  */
8
8
 
9
+ import { ComponentPropsWithRef, forwardRef } from "react";
9
10
  import { useTranslation } from "react-i18next";
10
- import styled from "@emotion/styled";
11
- import { breakpoints, colors, mq, spacing } from "@ndla/core";
12
- import Format from "./Format";
11
+ import { DownloadLine } from "@ndla/icons/common";
12
+ import { Text } from "@ndla/primitives";
13
+ import { SafeLink } from "@ndla/safelink";
14
+ import { HStack, styled } from "@ndla/styled-system/jsx";
15
+ import { linkOverlay } from "@ndla/styled-system/patterns";
16
+ import { FileListItem } from ".";
13
17
 
14
- interface Props {
18
+ export interface FileProps extends ComponentPropsWithRef<"div"> {
15
19
  title: string;
16
20
  url: string;
17
21
  fileExists: boolean;
18
22
  fileType: string;
23
+ fileSize?: string;
19
24
  }
25
+
20
26
  export interface FileType {
21
27
  title: string;
22
28
  formats: FileFormat[];
@@ -29,27 +35,56 @@ export interface FileFormat {
29
35
  tooltip: string;
30
36
  }
31
37
 
32
- const StyledFileItem = styled.li`
33
- background: ${colors.brand.greyLighter};
34
- display: flex;
35
- align-items: center;
36
- flex-wrap: wrap;
37
- margin-bottom: ${spacing.xsmall};
38
- padding: ${spacing.small};
39
- ${mq.range({ from: breakpoints.tablet })} {
40
- padding: ${spacing.small} ${spacing.normal};
41
- }
42
- `;
43
-
44
- const File = ({ title, url, fileExists, fileType }: Props) => {
45
- const { t } = useTranslation();
46
- const tooltip = `${t("download")} ${url.split("/").pop()}`;
47
-
48
- return (
49
- <StyledFileItem>
50
- <Format format={{ url, fileType, tooltip }} isPrimary title={title} isDeadLink={!fileExists} />
51
- </StyledFileItem>
52
- );
53
- };
54
-
55
- export default File;
38
+ const StyledSafeLink = styled(SafeLink, {
39
+ base: {
40
+ textUnderlineOffset: "2px",
41
+ textDecoration: "underline",
42
+ _hover: {
43
+ textDecoration: "none",
44
+ },
45
+ },
46
+ });
47
+
48
+ const StyledHStack = styled(HStack, {
49
+ base: {
50
+ position: "relative",
51
+ paddingBlock: "small",
52
+ paddingInlineEnd: "medium",
53
+ paddingInlineStart: "small",
54
+ width: "100%",
55
+ },
56
+ });
57
+
58
+ export const File = forwardRef<HTMLDivElement, FileProps>(
59
+ ({ title, url, fileExists, fileType, fileSize, ...rest }, ref) => {
60
+ const { t } = useTranslation();
61
+ const tooltip = `${t("download")} ${url.split("/").pop()}`;
62
+
63
+ return (
64
+ <StyledHStack justify="space-between" ref={ref} {...rest}>
65
+ <HStack gap="xxsmall">
66
+ <DownloadLine />
67
+ {fileExists ? (
68
+ <StyledSafeLink unstyled css={linkOverlay.raw()} to={url} title={tooltip}>
69
+ {title}
70
+ </StyledSafeLink>
71
+ ) : (
72
+ <Text textStyle="label.medium">{title}</Text>
73
+ )}
74
+ <Text textStyle="label.large" asChild consumeCss>
75
+ <span>({fileType?.toUpperCase()})</span>
76
+ </Text>
77
+ </HStack>
78
+ <Text textStyle="label.large" asChild consumeCss>
79
+ <span>{fileSize}</span>
80
+ </Text>
81
+ </StyledHStack>
82
+ );
83
+ },
84
+ );
85
+
86
+ export const FileListElement = ({ title, url, fileExists, fileType, fileSize }: FileProps) => (
87
+ <FileListItem>
88
+ <File title={title} url={url} fileExists={fileExists} fileType={fileType} fileSize={fileSize} />
89
+ </FileListItem>
90
+ );
@@ -6,10 +6,14 @@
6
6
  *
7
7
  */
8
8
 
9
- import { Meta, StoryObj } from "@storybook/react";
10
- import File from "./File";
11
- import FileList from "./FileList";
12
- import PdfFile from "./PdfFile";
9
+ import { Meta, StoryFn, StoryObj } from "@storybook/react";
10
+ import { Pencil } from "@ndla/icons/action";
11
+ import { DeleteForever, DragVertical } from "@ndla/icons/editor";
12
+ import { IconButton } from "@ndla/primitives";
13
+ import { HStack, styled } from "@ndla/styled-system/jsx";
14
+ import { File } from "./File";
15
+ import { FileListEmbed, FileListItem } from "./FileList";
16
+ import { PdfFile } from "./PdfFile";
13
17
 
14
18
  export default {
15
19
  title: "Components/FileList",
@@ -25,27 +29,132 @@ export default {
25
29
  fileType: "pdf",
26
30
  },
27
31
  render: (args) => (
28
- <FileList>
32
+ <ul>
29
33
  <File {...args} />
30
- </FileList>
34
+ </ul>
31
35
  ),
32
36
  } as Meta<typeof File>;
33
37
 
38
+ export const FileListStory: StoryFn<typeof File> = (args) => (
39
+ <ul>
40
+ <FileListItem>
41
+ <File {...args} />
42
+ </FileListItem>
43
+ <FileListItem>
44
+ <File {...args} />
45
+ </FileListItem>
46
+ <FileListItem>
47
+ <File {...args} />
48
+ </FileListItem>
49
+ </ul>
50
+ );
51
+
34
52
  export const FileNotFound: StoryObj<typeof File> = {
35
53
  args: { fileExists: false },
54
+ render: (args) => (
55
+ <ul>
56
+ <FileListItem>
57
+ <File {...args} />
58
+ </FileListItem>
59
+ </ul>
60
+ ),
36
61
  };
37
62
 
38
63
  export const SeveralFiles: StoryObj<typeof File> = {
39
64
  render: () => (
40
- <FileList>
41
- <File title="Fil 1" url="https://ndla.no/1" fileExists fileType="mp4" />
42
- <File title="Fil 2" url="https://ndla.no/2" fileExists={false} fileType="png" />
65
+ <FileListEmbed>
66
+ <FileListItem>
67
+ <File title="Fil 1" url="https://ndla.no/1" fileExists fileType="mp4" fileSize="100 mb" />
68
+ </FileListItem>
69
+ <FileListItem>
70
+ <File title="Fil 2" url="https://ndla.no/2" fileExists={false} fileType="png" fileSize="100 mb" />
71
+ </FileListItem>
72
+ <FileListItem>
73
+ <File title="Fil 3" url="https://ndla.no/3" fileExists fileType="docx" fileSize="100 mb" />
74
+ </FileListItem>
75
+ <FileListItem>
76
+ <File title="Fil 4" url="https://ndla.no/4" fileExists fileType="docx" fileSize="100 mb" />
77
+ </FileListItem>
78
+ </FileListEmbed>
79
+ ),
80
+ };
81
+
82
+ export const DifferentFiles: StoryObj<typeof File> = {
83
+ render: () => (
84
+ <FileListEmbed>
85
+ <FileListItem>
86
+ <File title="Fil 1" url="https://ndla.no/1" fileExists fileType="mp4" fileSize="100 mb" />
87
+ </FileListItem>
43
88
  <PdfFile
44
89
  title="Fil 3"
45
90
  url="https://api.test.ndla.no/files/131789/krypteringsaktivitet_-_til_fiendegruppe_bm.pdf"
46
91
  />
47
- <File title="Fil 3" url="https://ndla.no/3" fileExists fileType="docx" />
48
- <File title="Fil 4" url="https://ndla.no/4" fileExists fileType="docx" />
49
- </FileList>
92
+ <FileListItem>
93
+ <File title="Fil 3" url="https://ndla.no/3" fileExists fileType="docx" fileSize="100 mb" />
94
+ </FileListItem>
95
+ </FileListEmbed>
96
+ ),
97
+ };
98
+
99
+ export const NoHeader: StoryObj<typeof File> = {
100
+ render: () => (
101
+ <ul>
102
+ <FileListItem>
103
+ <File title="Fil 1" url="https://ndla.no/1" fileExists fileType="mp4" fileSize="100 mb" />
104
+ </FileListItem>
105
+ <FileListItem>
106
+ <File title="Fil 1" url="https://ndla.no/1" fileExists fileType="mp4" fileSize="100 mb" />
107
+ </FileListItem>
108
+ </ul>
109
+ ),
110
+ };
111
+
112
+ export const FilesWithButtons: StoryObj<typeof File> = {
113
+ render: () => (
114
+ <ul>
115
+ <FileListItem>
116
+ <File title="Fil 1" url="https://ndla.no/1" fileExists fileType="mp4" fileSize="100 mb" />
117
+ <HStack>
118
+ <IconButton variant="clear">
119
+ <Pencil />
120
+ </IconButton>
121
+ <IconButton variant="clear">
122
+ <DeleteForever />
123
+ </IconButton>
124
+ </HStack>
125
+ </FileListItem>
126
+ <FileListItem>
127
+ <File title="Fil 1" url="https://ndla.no/1" fileExists fileType="mp4" fileSize="100 mb" />
128
+ <HStack>
129
+ <IconButton variant="clear">
130
+ <Pencil />
131
+ </IconButton>
132
+ <IconButton variant="clear">
133
+ <DeleteForever />
134
+ </IconButton>
135
+ </HStack>
136
+ </FileListItem>
137
+ </ul>
138
+ ),
139
+ };
140
+
141
+ const StyledFileListItem = styled(FileListItem, {
142
+ base: {
143
+ paddingInlineStart: "xxsmall",
144
+ display: "flex",
145
+ gap: "xxsmall",
146
+ },
147
+ });
148
+
149
+ export const FilesWithDragHandle: StoryObj<typeof File> = {
150
+ render: () => (
151
+ <ul>
152
+ <StyledFileListItem>
153
+ <IconButton variant="clear">
154
+ <DragVertical />
155
+ </IconButton>
156
+ <File title="Fil 1" url="https://ndla.no/1" fileExists fileType="mp4" fileSize="100 mb" />
157
+ </StyledFileListItem>
158
+ </ul>
50
159
  ),
51
160
  };
@@ -6,49 +6,43 @@
6
6
  *
7
7
  */
8
8
 
9
- import { ComponentProps, ReactNode } from "react";
9
+ import { ComponentPropsWithoutRef } from "react";
10
10
  import { useTranslation } from "react-i18next";
11
- import styled from "@emotion/styled";
12
- import { colors, fonts, spacing } from "@ndla/core";
13
- import { Heading } from "@ndla/typography";
14
- interface Props extends ComponentProps<"section"> {
15
- children: ReactNode;
16
- headingButtons?: ReactNode;
17
- }
11
+ import { Heading } from "@ndla/primitives";
12
+ import { styled } from "@ndla/styled-system/jsx";
18
13
 
19
- const FileListSection = styled.section`
20
- margin: ${spacing.large} 0;
21
- padding: 0 0 ${spacing.normal} ${spacing.normal};
22
- border-left: 2px solid ${colors.brand.greyLightest};
23
- font-family: ${fonts.sans};
24
- `;
14
+ interface Props extends ComponentPropsWithoutRef<"div"> {}
25
15
 
26
- const FileListHeaderWrapper = styled.div`
27
- display: flex;
28
- justify-content: space-between;
29
- align-items: center;
30
- margin: 0 0 ${spacing.xsmall} 0;
31
- padding-bottom: ${spacing.xsmall};
32
- border-bottom: 2px solid ${colors.brand.greyLight};
33
- `;
16
+ export const FileListWrapper = styled("div", {
17
+ base: {
18
+ display: "flex",
19
+ flexDirection: "column",
20
+ gap: "xsmall",
21
+ },
22
+ });
34
23
 
35
- const FilesList = styled.ul`
36
- padding: 0;
37
- `;
24
+ export const FileListItem = styled("li", {
25
+ base: {
26
+ background: "surface.infoSubtle",
27
+ borderBlockEnd: "1px solid",
28
+ borderColor: "stroke.default",
29
+ display: "flex",
30
+ justifyContent: "space-between",
38
31
 
39
- const FileList = ({ children, headingButtons, ...rest }: Props) => {
32
+ _hover: {
33
+ backgroundColor: "surface.infoSubtle.hover",
34
+ },
35
+ },
36
+ });
37
+
38
+ export const FileListEmbed = ({ children, ...rest }: Props) => {
40
39
  const { t } = useTranslation();
41
40
  return (
42
- <FileListSection {...rest}>
43
- <FileListHeaderWrapper>
44
- <Heading element="h3" headingStyle="list-title" margin="none">
45
- {t("files")}
46
- </Heading>
47
- <div>{headingButtons}</div>
48
- </FileListHeaderWrapper>
49
- <FilesList>{children}</FilesList>
50
- </FileListSection>
41
+ <FileListWrapper {...rest} data-embed-type="file-list">
42
+ <Heading fontWeight="bold" textStyle="heading.small" asChild consumeCss>
43
+ <h3>{t("files")}</h3>
44
+ </Heading>
45
+ <ul>{children}</ul>
46
+ </FileListWrapper>
51
47
  );
52
48
  };
53
-
54
- export default FileList;
@@ -28,15 +28,15 @@ const StyledFigure = styled(Figure, {
28
28
  },
29
29
  });
30
30
 
31
- const PdfFile = ({ title, url }: Props) => {
31
+ export const PdfFile = ({ title, url }: Props) => {
32
32
  return (
33
- <StyledFigure>
34
- <Heading asChild consumeCss textStyle="title.medium">
35
- <h4>{title}</h4>
36
- </Heading>
37
- <StyledIframe title={title} height="1050" src={url} />
38
- </StyledFigure>
33
+ <li>
34
+ <StyledFigure>
35
+ <Heading asChild consumeCss textStyle="title.medium">
36
+ <h4>{title}</h4>
37
+ </Heading>
38
+ <StyledIframe title={title} height="1050" src={url} />
39
+ </StyledFigure>
40
+ </li>
39
41
  );
40
42
  };
41
-
42
- export default PdfFile;
@@ -6,10 +6,6 @@
6
6
  *
7
7
  */
8
8
 
9
- import FileList from "./FileList";
10
-
11
- export { default as File } from "./File";
12
- export { default as PdfFile } from "./PdfFile";
13
- export { default as Format } from "./Format";
14
-
15
- export default FileList;
9
+ export { FileListEmbed, FileListItem } from "./FileList";
10
+ export { File, FileListElement } from "./File";
11
+ export { PdfFile } from "./PdfFile";
@@ -6,52 +6,51 @@
6
6
  *
7
7
  */
8
8
 
9
- import styled from "@emotion/styled";
10
- import { DocsContainer, DocsContainerProps } from "@storybook/addon-docs";
11
9
  import { Meta, StoryFn } from "@storybook/react";
12
- import { colors } from "@ndla/core";
13
- import Grid from "./Grid";
10
+ import { ArticleContent, ArticleWrapper, OneColumn } from "@ndla/ui";
11
+ import { Grid } from "./Grid";
14
12
  import { BlogPostStory } from "../BlogPost/BlogPost.stories";
15
- import { KeyFigureStory } from "../KeyFigure/KeyFigure.stories";
16
-
17
- const GridWrapper = styled.div`
18
- .docs-story {
19
- background-color: ${colors.background.lightBlue};
20
- }
21
- `;
22
-
23
- const GridDocsContainer = ({ ...props }: DocsContainerProps) => (
24
- <GridWrapper>
25
- <DocsContainer {...props} />
26
- </GridWrapper>
27
- );
13
+ import { Plain } from "../KeyFigure/KeyFigure.stories";
28
14
 
29
15
  export default {
30
16
  title: "Components/Grid",
31
17
  component: Grid,
32
18
  tags: ["autodocs"],
33
19
  parameters: {
34
- layout: "centered",
35
- docs: {
36
- container: GridDocsContainer,
37
- },
20
+ inlineStories: true,
21
+ layout: "fullscreen",
38
22
  },
39
23
  args: {
40
- columns: "2",
24
+ columns: "3",
41
25
  border: "none",
42
- background: "white",
26
+ background: "gray",
43
27
  },
28
+ decorators: [
29
+ (Story) => (
30
+ <OneColumn wide>
31
+ <ArticleWrapper>
32
+ <ArticleContent>
33
+ <Story />
34
+ </ArticleContent>
35
+ </ArticleWrapper>
36
+ </OneColumn>
37
+ ),
38
+ ],
44
39
  } as Meta<typeof Grid>;
45
40
 
41
+ const keyFigureArgs = [
42
+ { title: "22 000+", subtitle: "Tilgjengelige ressurser" },
43
+ { title: "149", subtitle: "Eksamensfag" },
44
+ { title: "500", subtitle: "Tverrfaglige ressurser" },
45
+ { title: "0", subtitle: "Dårlige ideer" },
46
+ ];
47
+
46
48
  export const GridKeyPerformanceStory: StoryFn<typeof Grid> = ({ ...args }) => {
47
49
  const columns = args.columns === "2x2" ? 4 : parseInt(args.columns);
48
- const items = new Array(columns).fill(
49
- <KeyFigureStory
50
- title={KeyFigureStory.args?.title!}
51
- subtitle={KeyFigureStory.args?.subtitle!}
52
- image={KeyFigureStory.args?.image!}
53
- />,
54
- );
50
+ const items = new Array(columns).fill(0).map((_, idx) => {
51
+ const args = keyFigureArgs[idx % keyFigureArgs.length];
52
+ return <Plain key={idx} {...args} />;
53
+ });
55
54
  return <Grid {...args}>{items}</Grid>;
56
55
  };
57
56
 
@@ -61,7 +60,7 @@ export const GridBlogPostStory: StoryFn<typeof Grid> = ({ ...args }) => {
61
60
  <BlogPostStory
62
61
  metaImage={BlogPostStory.args?.metaImage!}
63
62
  title={BlogPostStory.args?.title!}
64
- size={BlogPostStory.args?.size}
63
+ size={"normal"}
65
64
  headingLevel={BlogPostStory.args?.headingLevel}
66
65
  url={BlogPostStory.args?.url!}
67
66
  author={BlogPostStory.args?.author}
package/src/Grid/Grid.tsx CHANGED
@@ -6,103 +6,75 @@
6
6
  *
7
7
  */
8
8
 
9
- import { HTMLAttributes, ReactNode } from "react";
10
- import styled from "@emotion/styled";
11
- import { breakpoints, colors, misc, mq, spacing } from "@ndla/core";
9
+ import { ReactNode } from "react";
10
+ import { styled } from "@ndla/styled-system/jsx";
11
+
12
+ const GridContainer = styled("div", {
13
+ base: {
14
+ display: "grid",
15
+ justifyContent: "center",
16
+ borderRadius: "xsmall",
17
+ padding: "xsmall",
18
+ gridRowGap: "large",
19
+ gridColumnGap: "medium",
20
+ width: "100%",
21
+ backgroundColor: "background.subtle",
22
+ maxWidth: "surface.4xlarge",
23
+ minWidth: "surface.xxsmall",
24
+ gridTemplateColumns: "repeat(2, minmax(0, 1fr))",
25
+ tabletDown: {
26
+ gridTemplateColumns: "repeat(1, minmax(0, 1fr))",
27
+ },
28
+ tabletToDesktop: {
29
+ gridTemplateColumns: "repeat(2, minmax(0, 1fr))",
30
+ "& > div:nth-child(3):last-child": {
31
+ display: "flex",
32
+ flexFlow: "column",
33
+ justifyContent: "center",
34
+ alignItems: "center",
35
+ gridColumn: "span 2",
36
+ },
37
+ },
38
+ },
39
+ variants: {
40
+ columns: {
41
+ "2": {},
42
+ "2x2": {},
43
+ "3": { desktop: { gridTemplateColumns: "repeat(3, minmax(0, 1fr))" } },
44
+ "4": { desktop: { gridTemplateColumns: "repeat(4, minmax(0, 1fr))" } },
45
+ },
46
+ background: {
47
+ white: { backgroundColor: "surface.default" },
48
+ transparent: { backgroundColor: "transparent" },
49
+ gray: { backgroundColor: "background.subtle" },
50
+ },
51
+ border: {
52
+ lightBlue: {
53
+ border: "1px solid",
54
+ borderColor: "surface.brand.2",
55
+ },
56
+ },
57
+ },
58
+ });
12
59
 
13
60
  export interface GridProps {
14
- columns: "2" | "4" | "2x2";
61
+ columns: "2" | "3" | "4" | "2x2";
15
62
  border?: "none" | "lightBlue";
16
- background?: "transparent" | "white";
17
- size?: boolean;
63
+ background?: "transparent" | "white" | "gray";
18
64
  children?: ReactNode[];
19
65
  }
20
66
 
21
- const GridContainer = styled.div`
22
- display: grid;
23
- justify-content: center;
24
- border-radius: ${misc.borderRadius};
25
- grid-template-columns: 1fr;
26
- grid-gap: ${spacing.normal};
27
- padding: ${spacing.normal};
28
- margin-bottom: ${spacing.normal};
29
- clear: both;
30
-
31
- ${mq.range({ until: breakpoints.tabletWide })} {
32
- &[data-columns="2x2"],
33
- &[data-columns="3"],
34
- &[data-columns="4"] {
35
- grid-template-columns: repeat(2, minmax(0, 1fr));
36
- }
37
- }
38
-
39
- ${mq.range({ until: breakpoints.desktop })} {
40
- > div:nth-child(3):last-child {
41
- display: flex;
42
- flex-flow: column;
43
- justify-content: center;
44
- align-items: center;
45
- grid-column: span 2;
46
- }
47
- }
48
-
49
- ${mq.range({ from: breakpoints.tabletWide })} {
50
- grid-template-columns: repeat(2, minmax(0, 1fr));
51
-
52
- &[data-columns="3"] {
53
- grid-template-columns: repeat(3, minmax(0, 1fr));
54
- }
55
-
56
- &[data-columns="4"] {
57
- grid-template-columns: repeat(4, minmax(0, 1fr));
58
- }
59
- }
60
-
61
- &[data-frontpage="true"] {
62
- grid-gap: ${spacing.large};
63
- }
64
-
65
- &[data-border="lightBlue"] {
66
- border: 1px solid ${colors.brand.lighter};
67
- }
68
- &[data-background="white"] {
69
- background-color: ${colors.white};
70
- }
71
-
72
- p {
73
- word-break: break-word;
74
- margin-top: 0px;
75
- }
76
- `;
77
-
78
- const Grid = ({ columns, border, children, background, size, ...rest }: GridProps) => {
67
+ export const Grid = ({ columns, border, children, background = "gray" }: GridProps) => {
79
68
  const amountOfColumns = children?.length === 3 ? "3" : columns;
80
69
 
81
70
  return (
82
71
  <GridContainer
83
- data-frontpage={size}
84
- data-border={border}
85
- data-columns={amountOfColumns}
86
- data-background={background}
87
- {...rest}
72
+ data-embed-type="grid"
73
+ border={border === "none" ? undefined : border}
74
+ columns={amountOfColumns}
75
+ background={background}
88
76
  >
89
77
  {children}
90
78
  </GridContainer>
91
79
  );
92
80
  };
93
-
94
- const StyledGridParallaxItem = styled.div`
95
- position: relative;
96
- > div {
97
- top: var(--masthead-height, 0px);
98
- position: sticky;
99
- }
100
- `;
101
-
102
- export const GridParallaxItem = ({ children, ...rest }: HTMLAttributes<HTMLDivElement>) => (
103
- <StyledGridParallaxItem {...rest}>
104
- <div>{children}</div>
105
- </StyledGridParallaxItem>
106
- );
107
-
108
- export default Grid;
@@ -0,0 +1,26 @@
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 { HTMLAttributes } from "react";
10
+ import { styled } from "@ndla/styled-system/jsx";
11
+
12
+ const StyledGridParallaxItem = styled("div", {
13
+ base: {
14
+ position: "relative",
15
+ "& > div": {
16
+ top: "var(--masthead-height, 0px)",
17
+ position: "sticky",
18
+ },
19
+ },
20
+ });
21
+
22
+ export const GridParallaxItem = ({ children, ...rest }: HTMLAttributes<HTMLDivElement>) => (
23
+ <StyledGridParallaxItem {...rest} data-embed-type="grid-parallax">
24
+ <div>{children}</div>
25
+ </StyledGridParallaxItem>
26
+ );
package/src/Grid/index.ts CHANGED
@@ -6,5 +6,7 @@
6
6
  *
7
7
  */
8
8
 
9
- export { default as Grid, GridParallaxItem } from "./Grid";
9
+ export { Grid } from "./Grid";
10
+ export { GridParallaxItem } from "./GridParallaxItem";
11
+
10
12
  export type { GridProps as GridType } from "./Grid";