@ndla/ui 53.0.1 → 54.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.
Files changed (72) hide show
  1. package/es/Embed/ConceptEmbed.js +14 -8
  2. package/es/Embed/RelatedContentEmbed.js +2 -1
  3. package/es/ErrorMessage/ErrorMessage.js +14 -17
  4. package/es/Figure/Figure.js +36 -20
  5. package/es/Layout/LayoutItem.js +20 -6
  6. package/es/Layout/index.js +0 -1
  7. package/es/List/OrderedList.js +12 -11
  8. package/es/TreeStructure/AddFolderButton.js +2 -2
  9. package/es/TreeStructure/ComboboxButton.js +2 -2
  10. package/es/TreeStructure/FolderItem.js +7 -7
  11. package/es/TreeStructure/FolderItems.js +2 -2
  12. package/es/TreeStructure/TreeStructure.js +5 -5
  13. package/es/all.css +1 -1
  14. package/es/index.js +1 -1
  15. package/lib/Embed/ConceptEmbed.d.ts +1 -0
  16. package/lib/Embed/ConceptEmbed.js +14 -8
  17. package/lib/Embed/RelatedContentEmbed.js +3 -1
  18. package/lib/ErrorMessage/ErrorMessage.js +14 -17
  19. package/lib/Figure/Figure.js +40 -20
  20. package/lib/Layout/LayoutItem.js +20 -8
  21. package/lib/Layout/index.d.ts +0 -1
  22. package/lib/Layout/index.js +0 -7
  23. package/lib/List/OrderedList.d.ts +0 -1
  24. package/lib/List/OrderedList.js +12 -12
  25. package/lib/TreeStructure/AddFolderButton.d.ts +1 -1
  26. package/lib/TreeStructure/AddFolderButton.js +2 -2
  27. package/lib/TreeStructure/ComboboxButton.d.ts +1 -1
  28. package/lib/TreeStructure/ComboboxButton.js +2 -2
  29. package/lib/TreeStructure/FolderItem.d.ts +1 -1
  30. package/lib/TreeStructure/FolderItem.js +7 -7
  31. package/lib/TreeStructure/FolderItems.d.ts +1 -1
  32. package/lib/TreeStructure/FolderItems.js +2 -2
  33. package/lib/TreeStructure/TreeStructure.d.ts +1 -1
  34. package/lib/TreeStructure/TreeStructure.js +5 -5
  35. package/lib/TreeStructure/arrowNavigation.d.ts +1 -1
  36. package/lib/TreeStructure/helperFunctions.d.ts +1 -1
  37. package/lib/TreeStructure/types.d.ts +1 -1
  38. package/lib/all.css +1 -1
  39. package/lib/index.d.ts +1 -1
  40. package/lib/index.js +0 -6
  41. package/package.json +16 -15
  42. package/src/Embed/AudioEmbed.stories.tsx +3 -3
  43. package/src/Embed/BrightcoveEmbed.stories.tsx +3 -3
  44. package/src/Embed/ConceptEmbed.stories.tsx +3 -3
  45. package/src/Embed/ConceptEmbed.tsx +20 -2
  46. package/src/Embed/ExternalEmbed.stories.tsx +3 -3
  47. package/src/Embed/H5pEmbed.stories.tsx +3 -3
  48. package/src/Embed/IframeEmbed.stories.tsx +3 -3
  49. package/src/Embed/ImageEmbed.stories.tsx +3 -3
  50. package/src/Embed/RelatedContentEmbed.stories.tsx +15 -3
  51. package/src/Embed/RelatedContentEmbed.tsx +4 -1
  52. package/src/Embed/UuDisclaimerEmbed.stories.tsx +3 -3
  53. package/src/ErrorMessage/ErrorMessage.tsx +8 -4
  54. package/src/Figure/Figure.tsx +102 -24
  55. package/src/Layout/LayoutItem.tsx +23 -6
  56. package/src/Layout/index.ts +0 -1
  57. package/src/List/OrderedList.stories.tsx +2 -2
  58. package/src/List/OrderedList.tsx +21 -18
  59. package/src/TreeStructure/AddFolderButton.tsx +1 -1
  60. package/src/TreeStructure/ComboboxButton.tsx +1 -1
  61. package/src/TreeStructure/FolderItem.tsx +1 -1
  62. package/src/TreeStructure/FolderItems.tsx +1 -1
  63. package/src/TreeStructure/TreeStructure.stories.tsx +1 -1
  64. package/src/TreeStructure/TreeStructure.tsx +1 -1
  65. package/src/TreeStructure/arrowNavigation.ts +1 -1
  66. package/src/TreeStructure/helperFunctions.ts +1 -1
  67. package/src/TreeStructure/types.ts +1 -1
  68. package/src/index.ts +1 -1
  69. package/es/Layout/Content.js +0 -19
  70. package/lib/Layout/Content.d.ts +0 -13
  71. package/lib/Layout/Content.js +0 -26
  72. package/src/Layout/Content.tsx +0 -17
package/lib/index.d.ts CHANGED
@@ -44,7 +44,7 @@ export { default as messagesSMA } from "./locale/messages-sma";
44
44
  export { default as Breadcrumb, HomeBreadcrumb } from "./Breadcrumb";
45
45
  export type { SimpleBreadcrumbItem, IndexedBreadcrumbItem } from "./Breadcrumb";
46
46
  export { i18nInstance, formatNestedMessages } from "./i18n";
47
- export { default as LayoutItem, OneColumn, PageContainer, Content } from "./Layout";
47
+ export { default as LayoutItem, OneColumn, PageContainer } from "./Layout";
48
48
  export { MediaList, MediaListItem, MediaListItemBody, MediaListItemActions, MediaListItemImage, MediaListItemMeta, } from "./MediaList";
49
49
  export type { ItemType } from "./MediaList";
50
50
  export { default as ContentTypeBadge, SubjectMaterialBadge, TasksAndActivitiesBadge, AssessmentResourcesBadge, LearningPathBadge, SubjectBadge, SourceMaterialBadge, ConceptBadge, } from "./ContentTypeBadge";
package/lib/index.js CHANGED
@@ -171,12 +171,6 @@ Object.defineProperty(exports, "ContactBlock", {
171
171
  return _ContactBlock.default;
172
172
  }
173
173
  });
174
- Object.defineProperty(exports, "Content", {
175
- enumerable: true,
176
- get: function () {
177
- return _Layout.Content;
178
- }
179
- });
180
174
  Object.defineProperty(exports, "ContentLinkEmbed", {
181
175
  enumerable: true,
182
176
  get: function () {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ndla/ui",
3
- "version": "53.0.1",
3
+ "version": "54.0.0",
4
4
  "description": "UI component library for NDLA.",
5
5
  "license": "GPL-3.0",
6
6
  "main": "lib/index.js",
@@ -31,19 +31,19 @@
31
31
  "types"
32
32
  ],
33
33
  "dependencies": {
34
- "@ndla/accordion": "^4.0.1",
35
- "@ndla/button": "^13.0.1",
36
- "@ndla/core": "^5.0.0",
37
- "@ndla/dropdown-menu": "^1.0.37",
38
- "@ndla/forms": "^8.0.1",
34
+ "@ndla/accordion": "^4.0.2",
35
+ "@ndla/button": "^13.0.2",
36
+ "@ndla/core": "^5.0.1",
37
+ "@ndla/dropdown-menu": "^1.0.38",
38
+ "@ndla/forms": "^8.0.2",
39
39
  "@ndla/hooks": "^2.1.7",
40
- "@ndla/icons": "^6.1.4",
40
+ "@ndla/icons": "^6.1.5",
41
41
  "@ndla/licenses": "^7.2.6",
42
- "@ndla/modal": "^6.0.0",
43
- "@ndla/notion": "^7.0.0",
44
- "@ndla/safelink": "^5.1.4",
45
- "@ndla/tooltip": "^8.0.0",
46
- "@ndla/typography": "^0.4.20",
42
+ "@ndla/modal": "^6.0.1",
43
+ "@ndla/notion": "^7.0.1",
44
+ "@ndla/safelink": "^5.1.5",
45
+ "@ndla/tooltip": "^8.0.1",
46
+ "@ndla/typography": "^0.4.21",
47
47
  "@ndla/util": "^4.0.4",
48
48
  "@radix-ui/react-popover": "^1.0.7",
49
49
  "@radix-ui/react-slider": "^1.1.2",
@@ -51,6 +51,7 @@
51
51
  "html-react-parser": "^5.1.8",
52
52
  "i18next-browser-languagedetector": "^7.1.0",
53
53
  "lodash.throttle": "^4.1.1",
54
+ "punycode.js": "^2.3.1",
54
55
  "react-device-detect": "^2.2.3",
55
56
  "react-select": "^5.8.0",
56
57
  "react-swipeable": "^7.0.0"
@@ -65,8 +66,8 @@
65
66
  "react-router-dom": "> 6.0.0"
66
67
  },
67
68
  "devDependencies": {
68
- "@ndla/types-backend": "^0.2.64",
69
- "@ndla/types-embed": "^4.1.6",
69
+ "@ndla/types-backend": "^0.2.82",
70
+ "@ndla/types-embed": "^4.1.7",
70
71
  "css-loader": "^6.7.3",
71
72
  "mini-css-extract-plugin": "^2.7.5",
72
73
  "sass-loader": "^13.2.2",
@@ -76,5 +77,5 @@
76
77
  "publishConfig": {
77
78
  "access": "public"
78
79
  },
79
- "gitHead": "974106ddedc78dd285be5b635e3fc534711f57fd"
80
+ "gitHead": "c778ba48c327f14eaae3e2da21ed24b183719167"
80
81
  }
@@ -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
- <section className="u-4/6@desktop u-push-1/6@desktop u-10/12@tablet u-push-1/12@tablet">
193
+ <LayoutItem layout="center">
194
194
  <section>
195
195
  <Story />
196
196
  </section>
197
- </section>
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
- <section className="u-4/6@desktop u-push-1/6@desktop u-10/12@tablet u-push-1/12@tablet">
166
+ <LayoutItem layout="center">
167
167
  <section>
168
168
  <Story />
169
169
  </section>
170
- </section>
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
- <section className="u-4/6@desktop u-push-1/6@desktop u-10/12@tablet u-push-1/12@tablet">
238
+ <LayoutItem layout="center">
239
239
  <section>
240
240
  <Story />
241
241
  </section>
242
- </section>
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 type={undefined}>
267
- <NotionButton role="button" data-open={modalPos !== -9999} tabIndex={0} ref={ref} {...rest}>
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
- <section className="u-4/6@desktop u-push-1/6@desktop u-10/12@tablet u-push-1/12@tablet">
60
+ <LayoutItem layout="center">
61
61
  <section>
62
62
  <Story />
63
63
  </section>
64
- </section>
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
- <section className="u-4/6@desktop u-push-1/6@desktop u-10/12@tablet u-push-1/12@tablet">
57
+ <LayoutItem layout="center">
58
58
  <section>
59
59
  <Story />
60
60
  </section>
61
- </section>
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
- <section className="u-4/6@desktop u-push-1/6@desktop u-10/12@tablet u-push-1/12@tablet">
32
+ <LayoutItem layout="center">
33
33
  <section>
34
34
  <Story />
35
35
  </section>
36
- </section>
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
- <section className="u-4/6@desktop u-push-1/6@desktop u-10/12@tablet u-push-1/12@tablet">
99
+ <LayoutItem layout="center">
100
100
  <section>
101
101
  <Story />
102
102
  </section>
103
- </section>
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
- <section className="u-4/6@desktop u-push-1/6@desktop u-10/12@tablet u-push-1/12@tablet">
372
+ <LayoutItem layout="center">
373
373
  <section>
374
374
  <Story />
375
375
  </section>
376
- </section>
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
- embedData.url.match(/^(?:https?:\/\/)?(?:[^@\n]+@)?(?:www\.)?([^:/\n]+)/im)?.[1] || embedData.url
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
- <section className="u-4/6@desktop u-push-1/6@desktop u-10/12@tablet u-push-1/12@tablet">
34
+ <LayoutItem layout="center">
35
35
  <section>
36
36
  <Story />
37
37
  </section>
38
- </section>
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
- <div css={{ marginTop: spacing.xsmall }}>
82
+ <MessageWrapper>
79
83
  <SafeLink to="/">{messages.goToFrontPage}</SafeLink>
80
- </div>
84
+ </MessageWrapper>
81
85
  )}
82
86
  {messages.logInFailed && (
83
- <div css={{ marginTop: spacing.xsmall }}>
87
+ <MessageWrapper>
84
88
  <SafeLink to="/minndla">{messages.logInFailed}</SafeLink>
85
- </div>
89
+ </MessageWrapper>
86
90
  )}
87
91
  {children}
88
92
  </StyledErrorMessage>
@@ -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 fullColumnStyle = css`
39
- left: auto !important;
40
- right: auto !important;
41
- width: auto !important;
42
- padding-left: 0;
43
- padding-right: 0;
44
- padding-bottom: ${spacing.large};
45
- margin-bottom: 0;
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 rightStyle = css`
49
- float: right;
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 smallTypes = ["small-right", "xsmall-right"];
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
- if (!floatClass) styles.push(fullColumnStyle);
60
- if (smallTypes.includes(type)) styles.push(rightStyle);
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
- }, [floatClass, type]);
63
-
64
- const classes = floatClass ? `${floatClass} ${className ?? ""}` : className;
142
+ }, [type]);
65
143
 
66
144
  return (
67
- <StyledFigure data-sizetype={type} css={styles} className={classes} {...rest} ref={ref}>
145
+ <StyledFigure data-sizetype={type} css={styles} {...rest} ref={ref}>
68
146
  {children}
69
147
  </StyledFigure>
70
148
  );
@@ -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 className = useMemo(() => {
35
+ const style = useMemo(() => {
18
36
  if (layout === "extend") {
19
- return "u-10/12@desktop u-push-1/12@desktop u-10/12@tablet u-push-1/12@tablet";
20
- }
21
- if (layout === "center") {
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 className={className} {...rest}>
45
+ <section css={style} {...rest}>
29
46
  {children}
30
47
  </section>
31
48
  );
@@ -10,6 +10,5 @@ import LayoutItem from "./LayoutItem";
10
10
 
11
11
  export { default as OneColumn } from "./OneColumn";
12
12
  export { default as PageContainer } from "./PageContainer";
13
- export { default as Content } from "./Content";
14
13
 
15
14
  export default LayoutItem;
@@ -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" className="ol-reset-5">
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 className="ol-reset-5" start={5}>
100
+ <OrderedList start={5}>
101
101
  <li>Listepunkt 1</li>
102
102
  <li>Listepunkt 2</li>
103
103
  <li>Listepunkt 3</li>