@ndla/ui 56.0.5-alpha.0 → 56.0.6-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 (43) hide show
  1. package/dist/panda.buildinfo.json +0 -4
  2. package/dist/styles.css +0 -14
  3. package/es/Article/Article.js +68 -29
  4. package/es/Article/index.js +1 -2
  5. package/es/CampaignBlock/CampaignBlock.js +0 -6
  6. package/es/Concept/Concept.js +1 -1
  7. package/es/Embed/ConceptEmbed.js +0 -4
  8. package/es/Embed/ImageEmbed.js +1 -4
  9. package/es/LinkBlock/LinkBlock.js +2 -2
  10. package/es/index.js +1 -1
  11. package/es/styles.css +0 -14
  12. package/es/utils/relativeUrl.js +4 -2
  13. package/lib/Article/Article.d.ts +22 -3
  14. package/lib/Article/Article.js +71 -31
  15. package/lib/Article/index.d.ts +1 -2
  16. package/lib/Article/index.js +19 -2
  17. package/lib/CampaignBlock/CampaignBlock.js +0 -6
  18. package/lib/Concept/Concept.js +1 -1
  19. package/lib/Embed/ConceptEmbed.js +0 -4
  20. package/lib/Embed/ImageEmbed.js +1 -4
  21. package/lib/LinkBlock/LinkBlock.js +2 -2
  22. package/lib/index.d.ts +1 -1
  23. package/lib/index.js +18 -0
  24. package/lib/styles.css +0 -14
  25. package/lib/types.d.ts +1 -1
  26. package/lib/utils/relativeUrl.js +4 -2
  27. package/package.json +7 -7
  28. package/src/Article/Article.tsx +69 -23
  29. package/src/Article/index.ts +10 -2
  30. package/src/CampaignBlock/CampaignBlock.tsx +0 -6
  31. package/src/Concept/Concept.tsx +2 -2
  32. package/src/ContactBlock/ContactBlock.tsx +0 -2
  33. package/src/Embed/ConceptEmbed.tsx +1 -5
  34. package/src/Embed/ImageEmbed.tsx +1 -3
  35. package/src/LinkBlock/LinkBlock.tsx +2 -2
  36. package/src/index.ts +3 -0
  37. package/src/types.ts +1 -1
  38. package/src/utils/__tests__/relativeUrl-test.tsx +12 -0
  39. package/src/utils/relativeUrl.ts +4 -2
  40. package/es/Article/ArticleContent.js +0 -27
  41. package/lib/Article/ArticleContent.d.ts +0 -11
  42. package/lib/Article/ArticleContent.js +0 -33
  43. package/src/Article/ArticleContent.tsx +0 -21
@@ -130,9 +130,6 @@
130
130
  "textDecoration]___[value:none]___[cond:_hover",
131
131
  "textDecoration]___[value:none]___[cond:_focusVisible",
132
132
  "display]___[value:none]___[cond:tabletDown",
133
- "maxWidth]___[value:surface.xsmall",
134
- "maxWidth]___[value:surface.medium]___[cond:mobileWide",
135
- "maxWidth]___[value:1100px]___[cond:tabletWide",
136
133
  "alignSelf]___[value:center",
137
134
  "height]___[value:215px",
138
135
  "height]___[value:340px]___[cond:desktop",
@@ -243,7 +240,6 @@
243
240
  "width]___[value:100%]___[cond:& iframe",
244
241
  "textStyle]___[value:label.xsmall]___[cond:& a",
245
242
  "marginInlineStart]___[value:1]___[cond:& a",
246
- "borderColor]___[value:surface.brand.1.strong",
247
243
  "borderBottom]___[value:0",
248
244
  "borderBottomLeftRadius]___[value:0",
249
245
  "borderBottomRightRadius]___[value:0",
package/dist/styles.css CHANGED
@@ -338,10 +338,6 @@
338
338
  text-decoration: underline;
339
339
  }
340
340
 
341
- .max-w_surface\.xsmall {
342
- max-width: var(--sizes-surface-xsmall);
343
- }
344
-
345
341
  .h_215px {
346
342
  height: 215px;
347
343
  }
@@ -722,10 +718,6 @@
722
718
  background-color: var(--colors-surface-disabled);
723
719
  }
724
720
 
725
- .bd-c_surface\.brand\.1\.strong {
726
- border-color: var(--colors-surface-brand-1-strong);
727
- }
728
-
729
721
  .bdr-bl_0 {
730
722
  border-bottom-left-radius: 0;
731
723
  }
@@ -1420,9 +1412,6 @@
1420
1412
  }
1421
1413
 
1422
1414
  @media screen and (min-width: 29.75rem) {
1423
- .mobileWide\:max-w_surface\.medium {
1424
- max-width: var(--sizes-surface-medium);
1425
- }
1426
1415
  .mobileWide\:d_none {
1427
1416
  display: none;
1428
1417
  }
@@ -1521,9 +1510,6 @@
1521
1510
  }
1522
1511
  .tabletWide\:max-w_532px {
1523
1512
  max-width: 532px;
1524
- }
1525
- .tabletWide\:max-w_1100px {
1526
- max-width: 1100px;
1527
1513
  }
1528
1514
  .tabletWide\:flex-d_row {
1529
1515
  flex-direction: row;
@@ -6,13 +6,29 @@
6
6
  *
7
7
  */
8
8
 
9
+ import { forwardRef } from "react";
10
+ import { ark } from "@ark-ui/react";
9
11
  import { Heading, Text } from "@ndla/primitives";
12
+ import { cx } from "@ndla/styled-system/css";
10
13
  import { styled } from "@ndla/styled-system/jsx";
11
14
  import ArticleByline from "./ArticleByline";
12
- import { ArticleContent } from "./ArticleContent";
13
15
  import { ContentTypeBadgeNew } from "..";
14
16
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
15
- export const ArticleWrapper = styled("article", {
17
+ const StyledArticleContent = styled(ark.section, {}, {
18
+ baseComponent: true
19
+ });
20
+ export const ArticleContent = /*#__PURE__*/forwardRef((_ref, ref) => {
21
+ let {
22
+ className,
23
+ ...props
24
+ } = _ref;
25
+ return /*#__PURE__*/_jsx(StyledArticleContent, {
26
+ className: cx("ndla-article", className),
27
+ ...props,
28
+ ref: ref
29
+ });
30
+ });
31
+ const StyledArticleWrapper = styled("article", {
16
32
  base: {
17
33
  display: "flex",
18
34
  flexDirection: "column",
@@ -41,7 +57,12 @@ export const ArticleWrapper = styled("article", {
41
57
  }
42
58
  }
43
59
  });
44
- const ArticleTitleWrapper = styled("hgroup", {
60
+ export const ArticleWrapper = /*#__PURE__*/forwardRef((props, ref) => /*#__PURE__*/_jsx(StyledArticleWrapper, {
61
+ "data-ndla-article": "",
62
+ ref: ref,
63
+ ...props
64
+ }));
65
+ export const ArticleHGroup = styled("hgroup", {
45
66
  base: {
46
67
  display: "flex",
47
68
  width: "100%",
@@ -53,7 +74,7 @@ const ArticleTitleWrapper = styled("hgroup", {
53
74
  }
54
75
  }
55
76
  });
56
- const ArticleFavoritesButtonWrapper = styled("div", {
77
+ export const ArticleActionWrapper = styled("div", {
57
78
  base: {
58
79
  position: "absolute",
59
80
  right: "8%",
@@ -83,7 +104,40 @@ export const ArticleFooter = styled("footer", {
83
104
  width: "100%"
84
105
  }
85
106
  });
86
- export const Article = _ref => {
107
+ export const ArticleTitle = _ref2 => {
108
+ let {
109
+ contentType,
110
+ heartButton,
111
+ title,
112
+ lang,
113
+ id,
114
+ introduction,
115
+ competenceGoals
116
+ } = _ref2;
117
+ return /*#__PURE__*/_jsxs(ArticleHeader, {
118
+ children: [/*#__PURE__*/_jsxs(ArticleHGroup, {
119
+ children: [!!contentType && /*#__PURE__*/_jsx(ContentTypeBadgeNew, {
120
+ contentType: contentType
121
+ }), !!heartButton && /*#__PURE__*/_jsx(ArticleActionWrapper, {
122
+ children: heartButton
123
+ }), /*#__PURE__*/_jsx(Heading, {
124
+ textStyle: "heading.large",
125
+ id: id,
126
+ lang: lang,
127
+ children: title
128
+ })]
129
+ }), !!introduction && /*#__PURE__*/_jsx(Text, {
130
+ lang: lang,
131
+ textStyle: "body.xlarge",
132
+ asChild: true,
133
+ consumeCss: true,
134
+ children: /*#__PURE__*/_jsx("div", {
135
+ children: introduction
136
+ })
137
+ }), competenceGoals]
138
+ });
139
+ };
140
+ export const Article = _ref3 => {
87
141
  let {
88
142
  article,
89
143
  contentType,
@@ -93,7 +147,7 @@ export const Article = _ref => {
93
147
  id,
94
148
  heartButton,
95
149
  lang
96
- } = _ref;
150
+ } = _ref3;
97
151
  const {
98
152
  title,
99
153
  introduction,
@@ -104,29 +158,14 @@ export const Article = _ref => {
104
158
  } = article;
105
159
  const authors = copyright?.creators.length || copyright?.rightsholders.length ? copyright.creators : copyright?.processors;
106
160
  return /*#__PURE__*/_jsxs(ArticleWrapper, {
107
- "data-ndla-article": "",
108
- children: [/*#__PURE__*/_jsxs(ArticleHeader, {
109
- children: [/*#__PURE__*/_jsxs(ArticleTitleWrapper, {
110
- children: [!!contentType && /*#__PURE__*/_jsx(ContentTypeBadgeNew, {
111
- contentType: contentType
112
- }), !!heartButton && /*#__PURE__*/_jsx(ArticleFavoritesButtonWrapper, {
113
- children: heartButton
114
- }), /*#__PURE__*/_jsx(Heading, {
115
- textStyle: "heading.large",
116
- id: id,
117
- tabIndex: -1,
118
- lang: lang,
119
- children: title
120
- })]
121
- }), !!introduction && /*#__PURE__*/_jsx(Text, {
122
- lang: lang,
123
- textStyle: "body.xlarge",
124
- asChild: true,
125
- consumeCss: true,
126
- children: /*#__PURE__*/_jsx("div", {
127
- children: introduction
128
- })
129
- }), competenceGoals]
161
+ children: [/*#__PURE__*/_jsx(ArticleTitle, {
162
+ id: id,
163
+ contentType: contentType,
164
+ heartButton: heartButton,
165
+ title: title,
166
+ introduction: introduction,
167
+ competenceGoals: competenceGoals,
168
+ lang: lang
130
169
  }), /*#__PURE__*/_jsx(ArticleContent, {
131
170
  children: content
132
171
  }), /*#__PURE__*/_jsxs(ArticleFooter, {
@@ -8,7 +8,6 @@
8
8
 
9
9
  import ArticleByline from "./ArticleByline";
10
10
  import ArticleFootNotes from "./ArticleFootNotes";
11
- export { Article, ArticleWrapper, ArticleHeader, ArticleFooter } from "./Article";
12
- export { ArticleContent } from "./ArticleContent";
11
+ export { Article, ArticleWrapper, ArticleHeader, ArticleFooter, ArticleTitle, ArticleActionWrapper, ArticleHGroup, ArticleContent } from "./Article";
13
12
  export { ArticleByline, ArticleFootNotes };
14
13
  export { ArticleParagraph } from "./ArticleParagraph";
@@ -23,14 +23,8 @@ const Container = styled("div", {
23
23
  borderRadius: "xsmall",
24
24
  boxShadow: "full",
25
25
  marginBlockEnd: "4xsmall",
26
- maxWidth: "surface.xsmall",
27
26
  overflow: "hidden",
28
- mobileWide: {
29
- maxWidth: "surface.medium"
30
- },
31
27
  tabletWide: {
32
- // TODO: This is probably not the correct max-width. And it should be a token
33
- maxWidth: "1100px",
34
28
  flexDirection: "row"
35
29
  }
36
30
  }
@@ -29,7 +29,7 @@ const ContentWrapper = styled("div", {
29
29
  }
30
30
  });
31
31
 
32
- // TODO: Figure out if we need to support tags, subjects and headerButtons.
32
+ // TODO: Figure out if we need to support headerButtons.
33
33
 
34
34
  export const Concept = /*#__PURE__*/forwardRef((_ref, ref) => {
35
35
  let {
@@ -69,10 +69,6 @@ export const ConceptEmbed = _ref => {
69
69
  children: parsedContent
70
70
  });
71
71
  };
72
- // TODO: Consider if we should make this act like the old concept popover.
73
- // Should it take up the entire screen height on mobile? I don't think we need to.
74
- // Should it always stay directly underneath the trigger?
75
-
76
72
  export const InlineConcept = /*#__PURE__*/forwardRef((_ref2, ref) => {
77
73
  let {
78
74
  linkText,
@@ -93,8 +93,7 @@ const ImageWrapper = styled("div", {
93
93
  border: {
94
94
  true: {
95
95
  border: "1px solid",
96
- // TODO: Not sure if we want this color.
97
- borderColor: "surface.brand.1.strong",
96
+ borderColor: "stroke.subtle",
98
97
  borderBottom: "0",
99
98
  borderRadius: "xsmall",
100
99
  borderBottomLeftRadius: "0",
@@ -127,8 +126,6 @@ const StyledFigure = styled(Figure, {
127
126
  }
128
127
  }
129
128
  });
130
-
131
- // TODO: Ask about BylineButton styling. Not included in design
132
129
  const BylineButton = styled("button", {
133
130
  base: {
134
131
  cursor: "pointer",
@@ -32,8 +32,8 @@ const StyledSafeLink = styled(SafeLink, {
32
32
  background: "surface.default",
33
33
  padding: "medium",
34
34
  border: "1px solid",
35
- // TODO: Check if this is correct. Not part of design. Also check if this should have border-radius.
36
- borderColor: "stroke.default",
35
+ borderColor: "stroke.subtle",
36
+ borderRadius: "xsmall",
37
37
  "& h3": {
38
38
  textDecoration: "underline"
39
39
  },
package/es/index.js CHANGED
@@ -11,7 +11,7 @@
11
11
 
12
12
  export { ImageEmbed, getCrop, getFocalPoint, AudioEmbed, H5pEmbed, ExternalEmbed, IframeEmbed, FootnoteEmbed, BrightcoveEmbed, ContentLinkEmbed, RelatedContentEmbed, ConceptEmbed, ConceptListEmbed, UnknownEmbed, InlineConcept, BlockConcept, UuDisclaimerEmbed, CopyrightEmbed, CodeEmbed } from "./Embed";
13
13
  export { LicenseLink, EmbedByline } from "./LicenseByline";
14
- export { ArticleByline, ArticleFootNotes, ArticleWrapper, Article, ArticleParagraph, ArticleFooter, ArticleHeader, ArticleContent } from "./Article";
14
+ export { ArticleByline, ArticleFootNotes, ArticleWrapper, Article, ArticleParagraph, ArticleFooter, ArticleHeader, ArticleContent, ArticleHGroup, ArticleActionWrapper, ArticleTitle } from "./Article";
15
15
  export { getPossiblyRelativeUrl } from "./utils/relativeUrl";
16
16
  export { default as ContentLoader } from "./ContentLoader";
17
17
  export { default as RelatedArticleList, RelatedArticle } from "./RelatedArticleList";
package/es/styles.css CHANGED
@@ -338,10 +338,6 @@
338
338
  text-decoration: underline;
339
339
  }
340
340
 
341
- .max-w_surface\.xsmall {
342
- max-width: var(--sizes-surface-xsmall);
343
- }
344
-
345
341
  .h_215px {
346
342
  height: 215px;
347
343
  }
@@ -722,10 +718,6 @@
722
718
  background-color: var(--colors-surface-disabled);
723
719
  }
724
720
 
725
- .bd-c_surface\.brand\.1\.strong {
726
- border-color: var(--colors-surface-brand-1-strong);
727
- }
728
-
729
721
  .bdr-bl_0 {
730
722
  border-bottom-left-radius: 0;
731
723
  }
@@ -1420,9 +1412,6 @@
1420
1412
  }
1421
1413
 
1422
1414
  @media screen and (min-width: 29.75rem) {
1423
- .mobileWide\:max-w_surface\.medium {
1424
- max-width: var(--sizes-surface-medium);
1425
- }
1426
1415
  .mobileWide\:d_none {
1427
1416
  display: none;
1428
1417
  }
@@ -1521,9 +1510,6 @@
1521
1510
  }
1522
1511
  .tabletWide\:max-w_532px {
1523
1512
  max-width: 532px;
1524
- }
1525
- .tabletWide\:max-w_1100px {
1526
- max-width: 1100px;
1527
1513
  }
1528
1514
  .tabletWide\:flex-d_row {
1529
1515
  flex-direction: row;
@@ -23,13 +23,15 @@ export const getPossiblyRelativeUrl = (url, path) => {
23
23
  // If the host is the same, return the relative path
24
24
  if (urlObj.hostname.replace(REPLACE_WWW, "") === pathObj.hostname.replace(REPLACE_WWW, "")) {
25
25
  // Replace the language part of the url with the language part of the path
26
+ // Keep the search params if they exist
27
+ const search = urlObj.search;
26
28
  // If the path language part does not exist, remove it.
27
29
  const urlMatch = urlObj.pathname.match(LANGUAGE_REGEX);
28
30
  const pathMatch = pathObj.pathname.match(LANGUAGE_REGEX);
29
31
  if (urlMatch?.[1] && urlMatch?.[1] !== pathMatch?.[1]) {
30
- return urlObj.pathname.replace(urlMatch[1], pathMatch?.[1] || "");
32
+ return `${urlObj.pathname.replace(urlMatch[1], pathMatch?.[1] || "")}${search}`;
31
33
  }
32
- return urlObj.pathname;
34
+ return `${urlObj.pathname}${search}`;
33
35
  }
34
36
  return url;
35
37
  };
@@ -8,10 +8,29 @@
8
8
  import { ReactNode } from "react";
9
9
  import { ContentType } from "../ContentTypeBadge/ContentTypeBadgeNew";
10
10
  import { Article as ArticleType } from "../types";
11
- export declare const ArticleWrapper: import("@ndla/styled-system/types").StyledComponent<"article", {}>;
11
+ export declare const ArticleContent: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("@ark-ui/react").PolymorphicProps & {
12
+ consumeCss?: boolean | undefined;
13
+ } & import("@ndla/styled-system/types").WithCss & import("react").RefAttributes<HTMLElement>>;
14
+ export declare const ArticleWrapper: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLElement>, HTMLElement>, "ref"> & {
15
+ ref?: ((instance: HTMLElement | null) => void) | import("react").RefObject<HTMLElement> | null | undefined;
16
+ } & {
17
+ consumeCss?: boolean | undefined;
18
+ } & import("@ndla/styled-system/types").WithCss, "ref"> & import("react").RefAttributes<HTMLElement>>;
19
+ export declare const ArticleHGroup: import("@ndla/styled-system/types").StyledComponent<"hgroup", {}>;
20
+ export declare const ArticleActionWrapper: import("@ndla/styled-system/types").StyledComponent<"div", {}>;
12
21
  export declare const ArticleHeader: import("@ndla/styled-system/types").StyledComponent<"header", {}>;
13
22
  export declare const ArticleFooter: import("@ndla/styled-system/types").StyledComponent<"footer", {}>;
14
- type Props = {
23
+ interface ArticleTitleProps {
24
+ heartButton?: ReactNode;
25
+ contentType?: ContentType;
26
+ competenceGoals?: ReactNode;
27
+ id: string;
28
+ lang?: string;
29
+ title?: ReactNode;
30
+ introduction?: ReactNode;
31
+ }
32
+ export declare const ArticleTitle: ({ contentType, heartButton, title, lang, id, introduction, competenceGoals, }: ArticleTitleProps) => import("react/jsx-runtime").JSX.Element;
33
+ interface Props {
15
34
  heartButton?: ReactNode;
16
35
  article: ArticleType;
17
36
  licenseBox?: ReactNode;
@@ -20,6 +39,6 @@ type Props = {
20
39
  competenceGoals?: ReactNode;
21
40
  id: string;
22
41
  lang?: string;
23
- };
42
+ }
24
43
  export declare const Article: ({ article, contentType, licenseBox, children, competenceGoals, id, heartButton, lang, }: Props) => import("react/jsx-runtime").JSX.Element;
25
44
  export {};
@@ -3,11 +3,13 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.ArticleWrapper = exports.ArticleHeader = exports.ArticleFooter = exports.Article = void 0;
6
+ exports.ArticleWrapper = exports.ArticleTitle = exports.ArticleHeader = exports.ArticleHGroup = exports.ArticleFooter = exports.ArticleContent = exports.ArticleActionWrapper = exports.Article = void 0;
7
+ var _react = require("react");
8
+ var _react2 = require("@ark-ui/react");
7
9
  var _primitives = require("@ndla/primitives");
10
+ var _css = require("@ndla/styled-system/css");
8
11
  var _jsx2 = require("@ndla/styled-system/jsx");
9
12
  var _ArticleByline = _interopRequireDefault(require("./ArticleByline"));
10
- var _ArticleContent = require("./ArticleContent");
11
13
  var _ = require("..");
12
14
  var _jsxRuntime = require("react/jsx-runtime");
13
15
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -19,7 +21,21 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
19
21
  *
20
22
  */
21
23
 
22
- const ArticleWrapper = exports.ArticleWrapper = (0, _jsx2.styled)("article", {
24
+ const StyledArticleContent = (0, _jsx2.styled)(_react2.ark.section, {}, {
25
+ baseComponent: true
26
+ });
27
+ const ArticleContent = exports.ArticleContent = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
28
+ let {
29
+ className,
30
+ ...props
31
+ } = _ref;
32
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(StyledArticleContent, {
33
+ className: (0, _css.cx)("ndla-article", className),
34
+ ...props,
35
+ ref: ref
36
+ });
37
+ });
38
+ const StyledArticleWrapper = (0, _jsx2.styled)("article", {
23
39
  base: {
24
40
  display: "flex",
25
41
  flexDirection: "column",
@@ -48,7 +64,12 @@ const ArticleWrapper = exports.ArticleWrapper = (0, _jsx2.styled)("article", {
48
64
  }
49
65
  }
50
66
  });
51
- const ArticleTitleWrapper = (0, _jsx2.styled)("hgroup", {
67
+ const ArticleWrapper = exports.ArticleWrapper = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => /*#__PURE__*/(0, _jsxRuntime.jsx)(StyledArticleWrapper, {
68
+ "data-ndla-article": "",
69
+ ref: ref,
70
+ ...props
71
+ }));
72
+ const ArticleHGroup = exports.ArticleHGroup = (0, _jsx2.styled)("hgroup", {
52
73
  base: {
53
74
  display: "flex",
54
75
  width: "100%",
@@ -60,7 +81,7 @@ const ArticleTitleWrapper = (0, _jsx2.styled)("hgroup", {
60
81
  }
61
82
  }
62
83
  });
63
- const ArticleFavoritesButtonWrapper = (0, _jsx2.styled)("div", {
84
+ const ArticleActionWrapper = exports.ArticleActionWrapper = (0, _jsx2.styled)("div", {
64
85
  base: {
65
86
  position: "absolute",
66
87
  right: "8%",
@@ -90,7 +111,41 @@ const ArticleFooter = exports.ArticleFooter = (0, _jsx2.styled)("footer", {
90
111
  width: "100%"
91
112
  }
92
113
  });
93
- const Article = _ref => {
114
+ const ArticleTitle = _ref2 => {
115
+ let {
116
+ contentType,
117
+ heartButton,
118
+ title,
119
+ lang,
120
+ id,
121
+ introduction,
122
+ competenceGoals
123
+ } = _ref2;
124
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(ArticleHeader, {
125
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(ArticleHGroup, {
126
+ children: [!!contentType && /*#__PURE__*/(0, _jsxRuntime.jsx)(_.ContentTypeBadgeNew, {
127
+ contentType: contentType
128
+ }), !!heartButton && /*#__PURE__*/(0, _jsxRuntime.jsx)(ArticleActionWrapper, {
129
+ children: heartButton
130
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.Heading, {
131
+ textStyle: "heading.large",
132
+ id: id,
133
+ lang: lang,
134
+ children: title
135
+ })]
136
+ }), !!introduction && /*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.Text, {
137
+ lang: lang,
138
+ textStyle: "body.xlarge",
139
+ asChild: true,
140
+ consumeCss: true,
141
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
142
+ children: introduction
143
+ })
144
+ }), competenceGoals]
145
+ });
146
+ };
147
+ exports.ArticleTitle = ArticleTitle;
148
+ const Article = _ref3 => {
94
149
  let {
95
150
  article,
96
151
  contentType,
@@ -100,7 +155,7 @@ const Article = _ref => {
100
155
  id,
101
156
  heartButton,
102
157
  lang
103
- } = _ref;
158
+ } = _ref3;
104
159
  const {
105
160
  title,
106
161
  introduction,
@@ -111,30 +166,15 @@ const Article = _ref => {
111
166
  } = article;
112
167
  const authors = copyright?.creators.length || copyright?.rightsholders.length ? copyright.creators : copyright?.processors;
113
168
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(ArticleWrapper, {
114
- "data-ndla-article": "",
115
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(ArticleHeader, {
116
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(ArticleTitleWrapper, {
117
- children: [!!contentType && /*#__PURE__*/(0, _jsxRuntime.jsx)(_.ContentTypeBadgeNew, {
118
- contentType: contentType
119
- }), !!heartButton && /*#__PURE__*/(0, _jsxRuntime.jsx)(ArticleFavoritesButtonWrapper, {
120
- children: heartButton
121
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.Heading, {
122
- textStyle: "heading.large",
123
- id: id,
124
- tabIndex: -1,
125
- lang: lang,
126
- children: title
127
- })]
128
- }), !!introduction && /*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.Text, {
129
- lang: lang,
130
- textStyle: "body.xlarge",
131
- asChild: true,
132
- consumeCss: true,
133
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
134
- children: introduction
135
- })
136
- }), competenceGoals]
137
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_ArticleContent.ArticleContent, {
169
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(ArticleTitle, {
170
+ id: id,
171
+ contentType: contentType,
172
+ heartButton: heartButton,
173
+ title: title,
174
+ introduction: introduction,
175
+ competenceGoals: competenceGoals,
176
+ lang: lang
177
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(ArticleContent, {
138
178
  children: content
139
179
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(ArticleFooter, {
140
180
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_ArticleByline.default, {
@@ -7,7 +7,6 @@
7
7
  */
8
8
  import ArticleByline from "./ArticleByline";
9
9
  import ArticleFootNotes from "./ArticleFootNotes";
10
- export { Article, ArticleWrapper, ArticleHeader, ArticleFooter } from "./Article";
11
- export { ArticleContent } from "./ArticleContent";
10
+ export { Article, ArticleWrapper, ArticleHeader, ArticleFooter, ArticleTitle, ArticleActionWrapper, ArticleHGroup, ArticleContent, } from "./Article";
12
11
  export { ArticleByline, ArticleFootNotes };
13
12
  export { ArticleParagraph } from "./ArticleParagraph";
@@ -9,6 +9,12 @@ Object.defineProperty(exports, "Article", {
9
9
  return _Article.Article;
10
10
  }
11
11
  });
12
+ Object.defineProperty(exports, "ArticleActionWrapper", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _Article.ArticleActionWrapper;
16
+ }
17
+ });
12
18
  Object.defineProperty(exports, "ArticleByline", {
13
19
  enumerable: true,
14
20
  get: function () {
@@ -18,7 +24,7 @@ Object.defineProperty(exports, "ArticleByline", {
18
24
  Object.defineProperty(exports, "ArticleContent", {
19
25
  enumerable: true,
20
26
  get: function () {
21
- return _ArticleContent.ArticleContent;
27
+ return _Article.ArticleContent;
22
28
  }
23
29
  });
24
30
  Object.defineProperty(exports, "ArticleFootNotes", {
@@ -33,6 +39,12 @@ Object.defineProperty(exports, "ArticleFooter", {
33
39
  return _Article.ArticleFooter;
34
40
  }
35
41
  });
42
+ Object.defineProperty(exports, "ArticleHGroup", {
43
+ enumerable: true,
44
+ get: function () {
45
+ return _Article.ArticleHGroup;
46
+ }
47
+ });
36
48
  Object.defineProperty(exports, "ArticleHeader", {
37
49
  enumerable: true,
38
50
  get: function () {
@@ -45,6 +57,12 @@ Object.defineProperty(exports, "ArticleParagraph", {
45
57
  return _ArticleParagraph.ArticleParagraph;
46
58
  }
47
59
  });
60
+ Object.defineProperty(exports, "ArticleTitle", {
61
+ enumerable: true,
62
+ get: function () {
63
+ return _Article.ArticleTitle;
64
+ }
65
+ });
48
66
  Object.defineProperty(exports, "ArticleWrapper", {
49
67
  enumerable: true,
50
68
  get: function () {
@@ -54,6 +72,5 @@ Object.defineProperty(exports, "ArticleWrapper", {
54
72
  var _ArticleByline = _interopRequireDefault(require("./ArticleByline"));
55
73
  var _ArticleFootNotes = _interopRequireDefault(require("./ArticleFootNotes"));
56
74
  var _Article = require("./Article");
57
- var _ArticleContent = require("./ArticleContent");
58
75
  var _ArticleParagraph = require("./ArticleParagraph");
59
76
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -30,14 +30,8 @@ const Container = (0, _jsx2.styled)("div", {
30
30
  borderRadius: "xsmall",
31
31
  boxShadow: "full",
32
32
  marginBlockEnd: "4xsmall",
33
- maxWidth: "surface.xsmall",
34
33
  overflow: "hidden",
35
- mobileWide: {
36
- maxWidth: "surface.medium"
37
- },
38
34
  tabletWide: {
39
- // TODO: This is probably not the correct max-width. And it should be a token
40
- maxWidth: "1100px",
41
35
  flexDirection: "row"
42
36
  }
43
37
  }
@@ -35,7 +35,7 @@ const ContentWrapper = (0, _jsx2.styled)("div", {
35
35
  }
36
36
  });
37
37
 
38
- // TODO: Figure out if we need to support tags, subjects and headerButtons.
38
+ // TODO: Figure out if we need to support headerButtons.
39
39
 
40
40
  const Concept = exports.Concept = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
41
41
  let {
@@ -77,10 +77,6 @@ const ConceptEmbed = _ref => {
77
77
  });
78
78
  };
79
79
  exports.ConceptEmbed = ConceptEmbed;
80
- // TODO: Consider if we should make this act like the old concept popover.
81
- // Should it take up the entire screen height on mobile? I don't think we need to.
82
- // Should it always stay directly underneath the trigger?
83
-
84
80
  const InlineConcept = exports.InlineConcept = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
85
81
  let {
86
82
  linkText,
@@ -103,8 +103,7 @@ const ImageWrapper = (0, _jsx2.styled)("div", {
103
103
  border: {
104
104
  true: {
105
105
  border: "1px solid",
106
- // TODO: Not sure if we want this color.
107
- borderColor: "surface.brand.1.strong",
106
+ borderColor: "stroke.subtle",
108
107
  borderBottom: "0",
109
108
  borderRadius: "xsmall",
110
109
  borderBottomLeftRadius: "0",
@@ -137,8 +136,6 @@ const StyledFigure = (0, _jsx2.styled)(_primitives.Figure, {
137
136
  }
138
137
  }
139
138
  });
140
-
141
- // TODO: Ask about BylineButton styling. Not included in design
142
139
  const BylineButton = (0, _jsx2.styled)("button", {
143
140
  base: {
144
141
  cursor: "pointer",
@@ -39,8 +39,8 @@ const StyledSafeLink = (0, _jsx2.styled)(_safelink.SafeLink, {
39
39
  background: "surface.default",
40
40
  padding: "medium",
41
41
  border: "1px solid",
42
- // TODO: Check if this is correct. Not part of design. Also check if this should have border-radius.
43
- borderColor: "stroke.default",
42
+ borderColor: "stroke.subtle",
43
+ borderRadius: "xsmall",
44
44
  "& h3": {
45
45
  textDecoration: "underline"
46
46
  },
package/lib/index.d.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  */
8
8
  export { ImageEmbed, getCrop, getFocalPoint, AudioEmbed, H5pEmbed, ExternalEmbed, IframeEmbed, FootnoteEmbed, BrightcoveEmbed, ContentLinkEmbed, RelatedContentEmbed, ConceptEmbed, ConceptListEmbed, UnknownEmbed, InlineConcept, BlockConcept, UuDisclaimerEmbed, CopyrightEmbed, CodeEmbed, } from "./Embed";
9
9
  export { LicenseLink, EmbedByline } from "./LicenseByline";
10
- export { ArticleByline, ArticleFootNotes, ArticleWrapper, Article, ArticleParagraph, ArticleFooter, ArticleHeader, ArticleContent, } from "./Article";
10
+ export { ArticleByline, ArticleFootNotes, ArticleWrapper, Article, ArticleParagraph, ArticleFooter, ArticleHeader, ArticleContent, ArticleHGroup, ArticleActionWrapper, ArticleTitle, } from "./Article";
11
11
  export { getPossiblyRelativeUrl } from "./utils/relativeUrl";
12
12
  export { default as ContentLoader } from "./ContentLoader";
13
13
  export { default as RelatedArticleList, RelatedArticle } from "./RelatedArticleList";
package/lib/index.js CHANGED
@@ -9,6 +9,12 @@ Object.defineProperty(exports, "Article", {
9
9
  return _Article.Article;
10
10
  }
11
11
  });
12
+ Object.defineProperty(exports, "ArticleActionWrapper", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _Article.ArticleActionWrapper;
16
+ }
17
+ });
12
18
  Object.defineProperty(exports, "ArticleByline", {
13
19
  enumerable: true,
14
20
  get: function () {
@@ -33,6 +39,12 @@ Object.defineProperty(exports, "ArticleFooter", {
33
39
  return _Article.ArticleFooter;
34
40
  }
35
41
  });
42
+ Object.defineProperty(exports, "ArticleHGroup", {
43
+ enumerable: true,
44
+ get: function () {
45
+ return _Article.ArticleHGroup;
46
+ }
47
+ });
36
48
  Object.defineProperty(exports, "ArticleHeader", {
37
49
  enumerable: true,
38
50
  get: function () {
@@ -45,6 +57,12 @@ Object.defineProperty(exports, "ArticleParagraph", {
45
57
  return _Article.ArticleParagraph;
46
58
  }
47
59
  });
60
+ Object.defineProperty(exports, "ArticleTitle", {
61
+ enumerable: true,
62
+ get: function () {
63
+ return _Article.ArticleTitle;
64
+ }
65
+ });
48
66
  Object.defineProperty(exports, "ArticleWrapper", {
49
67
  enumerable: true,
50
68
  get: function () {
package/lib/styles.css CHANGED
@@ -338,10 +338,6 @@
338
338
  text-decoration: underline;
339
339
  }
340
340
 
341
- .max-w_surface\.xsmall {
342
- max-width: var(--sizes-surface-xsmall);
343
- }
344
-
345
341
  .h_215px {
346
342
  height: 215px;
347
343
  }
@@ -722,10 +718,6 @@
722
718
  background-color: var(--colors-surface-disabled);
723
719
  }
724
720
 
725
- .bd-c_surface\.brand\.1\.strong {
726
- border-color: var(--colors-surface-brand-1-strong);
727
- }
728
-
729
721
  .bdr-bl_0 {
730
722
  border-bottom-left-radius: 0;
731
723
  }
@@ -1420,9 +1412,6 @@
1420
1412
  }
1421
1413
 
1422
1414
  @media screen and (min-width: 29.75rem) {
1423
- .mobileWide\:max-w_surface\.medium {
1424
- max-width: var(--sizes-surface-medium);
1425
- }
1426
1415
  .mobileWide\:d_none {
1427
1416
  display: none;
1428
1417
  }
@@ -1521,9 +1510,6 @@
1521
1510
  }
1522
1511
  .tabletWide\:max-w_532px {
1523
1512
  max-width: 532px;
1524
- }
1525
- .tabletWide\:max-w_1100px {
1526
- max-width: 1100px;
1527
1513
  }
1528
1514
  .tabletWide\:flex-d_row {
1529
1515
  flex-direction: row;
package/lib/types.d.ts CHANGED
@@ -36,7 +36,7 @@ export interface Copyright {
36
36
  rightsholders: Array<Contributor>;
37
37
  processors: Array<Contributor>;
38
38
  origin?: string;
39
- processed: boolean;
39
+ processed?: boolean;
40
40
  }
41
41
  export interface FootNote {
42
42
  ref: number;
@@ -29,13 +29,15 @@ const getPossiblyRelativeUrl = (url, path) => {
29
29
  // If the host is the same, return the relative path
30
30
  if (urlObj.hostname.replace(REPLACE_WWW, "") === pathObj.hostname.replace(REPLACE_WWW, "")) {
31
31
  // Replace the language part of the url with the language part of the path
32
+ // Keep the search params if they exist
33
+ const search = urlObj.search;
32
34
  // If the path language part does not exist, remove it.
33
35
  const urlMatch = urlObj.pathname.match(LANGUAGE_REGEX);
34
36
  const pathMatch = pathObj.pathname.match(LANGUAGE_REGEX);
35
37
  if (urlMatch?.[1] && urlMatch?.[1] !== pathMatch?.[1]) {
36
- return urlObj.pathname.replace(urlMatch[1], pathMatch?.[1] || "");
38
+ return `${urlObj.pathname.replace(urlMatch[1], pathMatch?.[1] || "")}${search}`;
37
39
  }
38
- return urlObj.pathname;
40
+ return `${urlObj.pathname}${search}`;
39
41
  }
40
42
  return url;
41
43
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ndla/ui",
3
- "version": "56.0.5-alpha.0",
3
+ "version": "56.0.6-alpha.0",
4
4
  "description": "UI component library for NDLA",
5
5
  "license": "GPL-3.0",
6
6
  "main": "lib/index.js",
@@ -33,13 +33,13 @@
33
33
  "types"
34
34
  ],
35
35
  "dependencies": {
36
- "@ndla/button": "^15.0.5-alpha.0",
36
+ "@ndla/button": "^15.0.6-alpha.0",
37
37
  "@ndla/core": "^5.0.1",
38
38
  "@ndla/hooks": "^2.1.8",
39
- "@ndla/icons": "^8.0.5-alpha.0",
39
+ "@ndla/icons": "^8.0.6-alpha.0",
40
40
  "@ndla/licenses": "^8.0.0-alpha.0",
41
- "@ndla/primitives": "^1.0.5-alpha.0",
42
- "@ndla/safelink": "^7.0.5-alpha.0",
41
+ "@ndla/primitives": "^1.0.6-alpha.0",
42
+ "@ndla/safelink": "^7.0.6-alpha.0",
43
43
  "@ndla/styled-system": "^0.0.10",
44
44
  "@ndla/typography": "^0.4.23",
45
45
  "@ndla/util": "^4.1.0",
@@ -60,7 +60,7 @@
60
60
  "react-router-dom": "> 6.0.0"
61
61
  },
62
62
  "devDependencies": {
63
- "@ndla/preset-panda": "^0.0.15",
63
+ "@ndla/preset-panda": "^0.0.16",
64
64
  "@ndla/types-backend": "^0.2.86",
65
65
  "@ndla/types-embed": "^5.0.0-alpha.0",
66
66
  "@pandacss/dev": "^0.44.0",
@@ -73,5 +73,5 @@
73
73
  "publishConfig": {
74
74
  "access": "public"
75
75
  },
76
- "gitHead": "1d1e87ed1d2fccefbc0ece2130f42d7d71cbe1a9"
76
+ "gitHead": "7770121967e96fe8d661b0f540e3397d6e2c453f"
77
77
  }
@@ -6,16 +6,26 @@
6
6
  *
7
7
  */
8
8
 
9
- import { ReactNode } from "react";
9
+ import { ComponentPropsWithRef, ReactNode, forwardRef } from "react";
10
+ import { ark, type HTMLArkProps } from "@ark-ui/react";
10
11
  import { Heading, Text } from "@ndla/primitives";
12
+ import { cx } from "@ndla/styled-system/css";
11
13
  import { styled } from "@ndla/styled-system/jsx";
14
+ import { JsxStyleProps } from "@ndla/styled-system/types";
12
15
  import ArticleByline from "./ArticleByline";
13
- import { ArticleContent } from "./ArticleContent";
14
16
  import { ContentTypeBadgeNew } from "..";
15
17
  import { ContentType } from "../ContentTypeBadge/ContentTypeBadgeNew";
16
18
  import { Article as ArticleType } from "../types";
17
19
 
18
- export const ArticleWrapper = styled("article", {
20
+ const StyledArticleContent = styled(ark.section, {}, { baseComponent: true });
21
+
22
+ export const ArticleContent = forwardRef<HTMLElement, HTMLArkProps<"div"> & JsxStyleProps>(
23
+ ({ className, ...props }, ref) => (
24
+ <StyledArticleContent className={cx("ndla-article", className)} {...props} ref={ref} />
25
+ ),
26
+ );
27
+
28
+ const StyledArticleWrapper = styled("article", {
19
29
  base: {
20
30
  display: "flex",
21
31
  flexDirection: "column",
@@ -45,7 +55,11 @@ export const ArticleWrapper = styled("article", {
45
55
  },
46
56
  });
47
57
 
48
- const ArticleTitleWrapper = styled("hgroup", {
58
+ export const ArticleWrapper = forwardRef<HTMLElement, ComponentPropsWithRef<"article"> & JsxStyleProps>(
59
+ (props, ref) => <StyledArticleWrapper data-ndla-article="" ref={ref} {...props} />,
60
+ );
61
+
62
+ export const ArticleHGroup = styled("hgroup", {
49
63
  base: {
50
64
  display: "flex",
51
65
  width: "100%",
@@ -58,7 +72,7 @@ const ArticleTitleWrapper = styled("hgroup", {
58
72
  },
59
73
  });
60
74
 
61
- const ArticleFavoritesButtonWrapper = styled("div", {
75
+ export const ArticleActionWrapper = styled("div", {
62
76
  base: {
63
77
  position: "absolute",
64
78
  right: "8%",
@@ -91,7 +105,45 @@ export const ArticleFooter = styled("footer", {
91
105
  },
92
106
  });
93
107
 
94
- type Props = {
108
+ interface ArticleTitleProps {
109
+ heartButton?: ReactNode;
110
+ contentType?: ContentType;
111
+ competenceGoals?: ReactNode;
112
+ id: string;
113
+ lang?: string;
114
+ title?: ReactNode;
115
+ introduction?: ReactNode;
116
+ }
117
+
118
+ export const ArticleTitle = ({
119
+ contentType,
120
+ heartButton,
121
+ title,
122
+ lang,
123
+ id,
124
+ introduction,
125
+ competenceGoals,
126
+ }: ArticleTitleProps) => {
127
+ return (
128
+ <ArticleHeader>
129
+ <ArticleHGroup>
130
+ {!!contentType && <ContentTypeBadgeNew contentType={contentType} />}
131
+ {!!heartButton && <ArticleActionWrapper>{heartButton}</ArticleActionWrapper>}
132
+ <Heading textStyle="heading.large" id={id} lang={lang}>
133
+ {title}
134
+ </Heading>
135
+ </ArticleHGroup>
136
+ {!!introduction && (
137
+ <Text lang={lang} textStyle="body.xlarge" asChild consumeCss>
138
+ <div>{introduction}</div>
139
+ </Text>
140
+ )}
141
+ {competenceGoals}
142
+ </ArticleHeader>
143
+ );
144
+ };
145
+
146
+ interface Props {
95
147
  heartButton?: ReactNode;
96
148
  article: ArticleType;
97
149
  licenseBox?: ReactNode;
@@ -100,7 +152,7 @@ type Props = {
100
152
  competenceGoals?: ReactNode;
101
153
  id: string;
102
154
  lang?: string;
103
- };
155
+ }
104
156
 
105
157
  export const Article = ({
106
158
  article,
@@ -118,22 +170,16 @@ export const Article = ({
118
170
  copyright?.creators.length || copyright?.rightsholders.length ? copyright.creators : copyright?.processors;
119
171
 
120
172
  return (
121
- <ArticleWrapper data-ndla-article="">
122
- <ArticleHeader>
123
- <ArticleTitleWrapper>
124
- {!!contentType && <ContentTypeBadgeNew contentType={contentType} />}
125
- {!!heartButton && <ArticleFavoritesButtonWrapper>{heartButton}</ArticleFavoritesButtonWrapper>}
126
- <Heading textStyle="heading.large" id={id} tabIndex={-1} lang={lang}>
127
- {title}
128
- </Heading>
129
- </ArticleTitleWrapper>
130
- {!!introduction && (
131
- <Text lang={lang} textStyle="body.xlarge" asChild consumeCss>
132
- <div>{introduction}</div>
133
- </Text>
134
- )}
135
- {competenceGoals}
136
- </ArticleHeader>
173
+ <ArticleWrapper>
174
+ <ArticleTitle
175
+ id={id}
176
+ contentType={contentType}
177
+ heartButton={heartButton}
178
+ title={title}
179
+ introduction={introduction}
180
+ competenceGoals={competenceGoals}
181
+ lang={lang}
182
+ />
137
183
  <ArticleContent>{content}</ArticleContent>
138
184
  <ArticleFooter>
139
185
  <ArticleByline
@@ -9,8 +9,16 @@
9
9
  import ArticleByline from "./ArticleByline";
10
10
  import ArticleFootNotes from "./ArticleFootNotes";
11
11
 
12
- export { Article, ArticleWrapper, ArticleHeader, ArticleFooter } from "./Article";
13
- export { ArticleContent } from "./ArticleContent";
12
+ export {
13
+ Article,
14
+ ArticleWrapper,
15
+ ArticleHeader,
16
+ ArticleFooter,
17
+ ArticleTitle,
18
+ ArticleActionWrapper,
19
+ ArticleHGroup,
20
+ ArticleContent,
21
+ } from "./Article";
14
22
 
15
23
  export { ArticleByline, ArticleFootNotes };
16
24
  export { ArticleParagraph } from "./ArticleParagraph";
@@ -44,14 +44,8 @@ const Container = styled("div", {
44
44
  borderRadius: "xsmall",
45
45
  boxShadow: "full",
46
46
  marginBlockEnd: "4xsmall",
47
- maxWidth: "surface.xsmall",
48
47
  overflow: "hidden",
49
- mobileWide: {
50
- maxWidth: "surface.medium",
51
- },
52
48
  tabletWide: {
53
- // TODO: This is probably not the correct max-width. And it should be a token
54
- maxWidth: "1100px",
55
49
  flexDirection: "row",
56
50
  },
57
51
  },
@@ -12,7 +12,7 @@ import { styled } from "@ndla/styled-system/jsx";
12
12
  import { IDraftCopyright as ConceptCopyright } from "@ndla/types-backend/concept-api";
13
13
  import { ConceptVisualElementMeta } from "@ndla/types-embed";
14
14
  import { BrightcoveEmbed, ExternalEmbed, H5pEmbed, IframeEmbed, ImageEmbed } from "../Embed";
15
- import { EmbedByline, LicenseContainerContent } from "../LicenseByline/EmbedByline";
15
+ import { EmbedByline } from "../LicenseByline/EmbedByline";
16
16
 
17
17
  export interface ConceptProps extends ComponentPropsWithRef<"figure"> {
18
18
  copyright?: ConceptCopyright;
@@ -40,7 +40,7 @@ const ContentWrapper = styled("div", {
40
40
  },
41
41
  });
42
42
 
43
- // TODO: Figure out if we need to support tags, subjects and headerButtons.
43
+ // TODO: Figure out if we need to support headerButtons.
44
44
 
45
45
  export const Concept = forwardRef<HTMLElement, ConceptProps>(
46
46
  ({ copyright, visualElement, lang, children, title, ...rest }, ref) => {
@@ -171,7 +171,6 @@ export const ContactBlock = ({
171
171
  <StyledWrapper data-embed-type="contact-block">
172
172
  <ContentWrapper>
173
173
  <HeaderWrapper variant={backgroundColor} imageExists={!!image}>
174
- {/* TODO: The font in the design specified `Source Sans Pro` and this is the default `Satoshi` */}
175
174
  <Text lang={lang} fontWeight="bold" textStyle="heading.small">
176
175
  {name}
177
176
  </Text>
@@ -191,7 +190,6 @@ export const ContactBlock = ({
191
190
  width={300}
192
191
  height={300}
193
192
  />
194
- {/* TODO: The font in the design specified `Source Sans Pro` and this is the default `Satoshi` */}
195
193
  <LicenseContainerContent type="image" copyright={image.copyright} />
196
194
  </ImageWrapper>
197
195
  )}
@@ -8,7 +8,7 @@
8
8
 
9
9
  import parse from "html-react-parser";
10
10
  import { forwardRef, useMemo } from "react";
11
- import { Figure, PopoverContent, PopoverRoot, PopoverTrigger } from "@ndla/primitives";
11
+ import { PopoverContent, PopoverRoot, PopoverTrigger } from "@ndla/primitives";
12
12
  import { styled } from "@ndla/styled-system/jsx";
13
13
  import { ConceptMetaData } from "@ndla/types-embed";
14
14
  import EmbedErrorPlaceholder from "./EmbedErrorPlaceholder";
@@ -82,10 +82,6 @@ export interface InlineConceptProps extends ConceptProps, BaseProps {
82
82
  linkText?: string;
83
83
  }
84
84
 
85
- // TODO: Consider if we should make this act like the old concept popover.
86
- // Should it take up the entire screen height on mobile? I don't think we need to.
87
- // Should it always stay directly underneath the trigger?
88
-
89
85
  export const InlineConcept = forwardRef<HTMLSpanElement, InlineConceptProps>(
90
86
  ({ linkText, copyright, visualElement, lang, children, title, ...rest }, ref) => (
91
87
  <PopoverRoot>
@@ -121,8 +121,7 @@ const ImageWrapper = styled("div", {
121
121
  border: {
122
122
  true: {
123
123
  border: "1px solid",
124
- // TODO: Not sure if we want this color.
125
- borderColor: "surface.brand.1.strong",
124
+ borderColor: "stroke.subtle",
126
125
  borderBottom: "0",
127
126
  borderRadius: "xsmall",
128
127
  borderBottomLeftRadius: "0",
@@ -157,7 +156,6 @@ const StyledFigure = styled(Figure, {
157
156
  },
158
157
  });
159
158
 
160
- // TODO: Ask about BylineButton styling. Not included in design
161
159
  const BylineButton = styled(
162
160
  "button",
163
161
  {
@@ -34,8 +34,8 @@ const StyledSafeLink = styled(SafeLink, {
34
34
  background: "surface.default",
35
35
  padding: "medium",
36
36
  border: "1px solid",
37
- // TODO: Check if this is correct. Not part of design. Also check if this should have border-radius.
38
- borderColor: "stroke.default",
37
+ borderColor: "stroke.subtle",
38
+ borderRadius: "xsmall",
39
39
  "& h3": {
40
40
  textDecoration: "underline",
41
41
  },
package/src/index.ts CHANGED
@@ -42,6 +42,9 @@ export {
42
42
  ArticleFooter,
43
43
  ArticleHeader,
44
44
  ArticleContent,
45
+ ArticleHGroup,
46
+ ArticleActionWrapper,
47
+ ArticleTitle,
45
48
  } from "./Article";
46
49
 
47
50
  export { getPossiblyRelativeUrl } from "./utils/relativeUrl";
package/src/types.ts CHANGED
@@ -43,7 +43,7 @@ export interface Copyright {
43
43
  rightsholders: Array<Contributor>;
44
44
  processors: Array<Contributor>;
45
45
  origin?: string;
46
- processed: boolean;
46
+ processed?: boolean;
47
47
  }
48
48
 
49
49
  export interface FootNote {
@@ -75,4 +75,16 @@ describe("getPossibleRelativeUrl", () => {
75
75
 
76
76
  expect(getPossiblyRelativeUrl(url, pathname)).toEqual("mailto:test@ndla.no");
77
77
  });
78
+ it("handles params in url", () => {
79
+ const url = "https://ndla.no/search?grepCodes=KM123";
80
+ const pathname = "https://ndla.no/article/666";
81
+
82
+ expect(getPossiblyRelativeUrl(url, pathname)).toEqual("/search?grepCodes=KM123");
83
+ });
84
+ it("handles params in url including language tag", () => {
85
+ const url = "https://ndla.no/nb/search?grepCodes=KM123";
86
+ const pathname = "https://ndla.no/en/article/666";
87
+
88
+ expect(getPossiblyRelativeUrl(url, pathname)).toEqual("/en/search?grepCodes=KM123");
89
+ });
78
90
  });
@@ -26,14 +26,16 @@ export const getPossiblyRelativeUrl = (url: string, path?: string) => {
26
26
  // If the host is the same, return the relative path
27
27
  if (urlObj.hostname.replace(REPLACE_WWW, "") === pathObj.hostname.replace(REPLACE_WWW, "")) {
28
28
  // Replace the language part of the url with the language part of the path
29
+ // Keep the search params if they exist
30
+ const search = urlObj.search;
29
31
  // If the path language part does not exist, remove it.
30
32
  const urlMatch = urlObj.pathname.match(LANGUAGE_REGEX);
31
33
  const pathMatch = pathObj.pathname.match(LANGUAGE_REGEX);
32
34
  if (urlMatch?.[1] && urlMatch?.[1] !== pathMatch?.[1]) {
33
- return urlObj.pathname.replace(urlMatch[1], pathMatch?.[1] || "");
35
+ return `${urlObj.pathname.replace(urlMatch[1], pathMatch?.[1] || "")}${search}`;
34
36
  }
35
37
 
36
- return urlObj.pathname;
38
+ return `${urlObj.pathname}${search}`;
37
39
  }
38
40
  return url;
39
41
  };
@@ -1,27 +0,0 @@
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 { forwardRef } from "react";
10
- import { ark } from "@ark-ui/react";
11
- import { cx } from "@ndla/styled-system/css";
12
- import { styled } from "@ndla/styled-system/jsx";
13
- import { jsx as _jsx } from "react/jsx-runtime";
14
- const StyledArticleContent = styled(ark.section, {}, {
15
- baseComponent: true
16
- });
17
- export const ArticleContent = /*#__PURE__*/forwardRef((_ref, ref) => {
18
- let {
19
- className,
20
- ...props
21
- } = _ref;
22
- return /*#__PURE__*/_jsx(StyledArticleContent, {
23
- className: cx("ndla-article", className),
24
- ...props,
25
- ref: ref
26
- });
27
- });
@@ -1,11 +0,0 @@
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
- /// <reference types="react" />
9
- export declare const ArticleContent: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("@ark-ui/react").PolymorphicProps & {
10
- consumeCss?: boolean | undefined;
11
- } & import("@ndla/styled-system/types").WithCss & import("react").RefAttributes<HTMLElement>>;
@@ -1,33 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.ArticleContent = void 0;
7
- var _react = require("react");
8
- var _react2 = require("@ark-ui/react");
9
- var _css = require("@ndla/styled-system/css");
10
- var _jsx2 = require("@ndla/styled-system/jsx");
11
- var _jsxRuntime = require("react/jsx-runtime");
12
- /**
13
- * Copyright (c) 2024-present, NDLA.
14
- *
15
- * This source code is licensed under the GPLv3 license found in the
16
- * LICENSE file in the root directory of this source tree.
17
- *
18
- */
19
-
20
- const StyledArticleContent = (0, _jsx2.styled)(_react2.ark.section, {}, {
21
- baseComponent: true
22
- });
23
- const ArticleContent = exports.ArticleContent = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
24
- let {
25
- className,
26
- ...props
27
- } = _ref;
28
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(StyledArticleContent, {
29
- className: (0, _css.cx)("ndla-article", className),
30
- ...props,
31
- ref: ref
32
- });
33
- });
@@ -1,21 +0,0 @@
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 { forwardRef } from "react";
10
- import { ark, type HTMLArkProps } from "@ark-ui/react";
11
- import { cx } from "@ndla/styled-system/css";
12
- import { styled } from "@ndla/styled-system/jsx";
13
- import { JsxStyleProps } from "@ndla/styled-system/types";
14
-
15
- const StyledArticleContent = styled(ark.section, {}, { baseComponent: true });
16
-
17
- export const ArticleContent = forwardRef<HTMLElement, HTMLArkProps<"div"> & JsxStyleProps>(
18
- ({ className, ...props }, ref) => (
19
- <StyledArticleContent className={cx("ndla-article", className)} {...props} ref={ref} />
20
- ),
21
- );