@ndla/ui 56.0.86-alpha.0 → 56.0.87-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.
@@ -218,6 +218,16 @@
218
218
  "clear]___[value:both]___[cond:& + [data-embed-wrapper]",
219
219
  "height]___[value:auto]___[cond:& iframe",
220
220
  "width]___[value:100%]___[cond:& iframe",
221
+ "color]___[value:text.link",
222
+ "textDecoration]___[value:unset]___[cond:_hover",
223
+ "gap]___[value:small",
224
+ "backgroundColor]___[value:surface.brand.2.subtle",
225
+ "borderRadius]___[value:xxsmall",
226
+ "borderColor]___[value:stroke.info",
227
+ "textOverflow]___[value:ellipsis",
228
+ "whiteSpace]___[value:nowrap",
229
+ "inset]___[value:0]___[cond:_before",
230
+ "zIndex]___[value:0]___[cond:_before",
221
231
  "textStyle]___[value:label.xsmall]___[cond:& a",
222
232
  "marginInlineStart]___[value:1]___[cond:& a",
223
233
  "borderRadius]___[value:0]___[cond:& img",
@@ -242,8 +252,6 @@
242
252
  "transitionDuration]___[value:normal]___[cond:& svg",
243
253
  "transitionTimingFunction]___[value:ease-out]___[cond:& svg",
244
254
  "paddingInlineStart]___[value:4xsmall",
245
- "color]___[value:text.link",
246
- "whiteSpace]___[value:nowrap",
247
255
  "textDecoration]___[value:none]___[cond:_focusWithin",
248
256
  "color]___[value:text.strong]___[cond:& a",
249
257
  "marginTop]___[value:0]___[cond:& h1",
@@ -291,12 +299,9 @@
291
299
  "paddingInlineEnd]___[value:medium",
292
300
  "paddingInlineStart]___[value:small",
293
301
  "flexDirection]___[value:row",
294
- "inset]___[value:0]___[cond:_before",
295
- "zIndex]___[value:0]___[cond:_before",
296
302
  "background]___[value:surface.infoSubtle",
297
303
  "borderBlockEnd]___[value:1px solid",
298
304
  "backgroundColor]___[value:surface.infoSubtle.hover]___[cond:_hover",
299
- "gap]___[value:small",
300
305
  "paddingInline]___[value:0",
301
306
  "background]___[value:surface.brand.1.subtle]___[cond:_first",
302
307
  "borderColor]___[value:stroke.default]___[cond:_first",
package/dist/styles.css CHANGED
@@ -441,6 +441,26 @@
441
441
  background: var(--colors-background-subtle);
442
442
  }
443
443
 
444
+ .c_text\.link {
445
+ color: var(--colors-text-link);
446
+ }
447
+
448
+ .gap_small {
449
+ gap: var(--spacing-small);
450
+ }
451
+
452
+ .bdr_xxsmall {
453
+ border-radius: xxsmall;
454
+ }
455
+
456
+ .tov_ellipsis {
457
+ text-overflow: ellipsis;
458
+ }
459
+
460
+ .white-space_nowrap {
461
+ white-space: nowrap;
462
+ }
463
+
444
464
  .z_docked {
445
465
  z-index: var(--z-index-docked);
446
466
  }
@@ -473,14 +493,6 @@
473
493
  padding-inline-start: var(--spacing-4xsmall);
474
494
  }
475
495
 
476
- .c_text\.link {
477
- color: var(--colors-text-link);
478
- }
479
-
480
- .white-space_nowrap {
481
- white-space: nowrap;
482
- }
483
-
484
496
  .my_xxlarge {
485
497
  margin-block: var(--spacing-xxlarge);
486
498
  }
@@ -509,10 +521,6 @@
509
521
  border-block-end: 1px solid;
510
522
  }
511
523
 
512
- .gap_small {
513
- gap: var(--spacing-small);
514
- }
515
-
516
524
  .px_0 {
517
525
  padding-inline: 0;
518
526
  }
@@ -669,6 +677,14 @@
669
677
  border-color: var(--colors-stroke-hover);
670
678
  }
671
679
 
680
+ .bg-c_surface\.brand\.2\.subtle {
681
+ background-color: var(--colors-surface-brand-2-subtle);
682
+ }
683
+
684
+ .bd-c_stroke\.info {
685
+ border-color: var(--colors-stroke-info);
686
+ }
687
+
672
688
  .top_xsmall {
673
689
  top: var(--spacing-xsmall);
674
690
  }
@@ -895,6 +911,14 @@
895
911
  width: 100%;
896
912
  }
897
913
 
914
+ .before\:inset_0::before {
915
+ inset: 0;
916
+ }
917
+
918
+ .before\:z_0::before {
919
+ z-index: 0;
920
+ }
921
+
898
922
  .\[\&_a\]\:ms_1 a {
899
923
  margin-inline-start: var(--spacing-1);
900
924
  }
@@ -963,14 +987,6 @@
963
987
  padding-block-end: var(--spacing-xsmall);
964
988
  }
965
989
 
966
- .before\:inset_0::before {
967
- inset: 0;
968
- }
969
-
970
- .before\:z_0::before {
971
- z-index: 0;
972
- }
973
-
974
990
  .first\:bg_surface\.brand\.1\.subtle:first-child {
975
991
  background: var(--colors-surface-brand-1-subtle);
976
992
  }
@@ -1126,6 +1142,10 @@
1126
1142
  background: var(--colors-surface-action-subtle-hover);
1127
1143
  }
1128
1144
 
1145
+ .hover\:td_unset:is(:hover, [data-hover]) {
1146
+ text-decoration: unset;
1147
+ }
1148
+
1129
1149
  .hover\:bd-c_text\.link:is(:hover, [data-hover]) {
1130
1150
  border-color: var(--colors-text-link);
1131
1151
  }
@@ -8,11 +8,14 @@
8
8
 
9
9
  import { useEffect, useRef } from "react";
10
10
  import { useTranslation } from "react-i18next";
11
- import { Figure } from "@ndla/primitives";
11
+ import { ArrowRightShortLine } from "@ndla/icons";
12
+ import { Figure, Text } from "@ndla/primitives";
13
+ import { SafeLink } from "@ndla/safelink";
12
14
  import { styled } from "@ndla/styled-system/jsx";
15
+ import { linkOverlay } from "@ndla/styled-system/patterns";
13
16
  import EmbedErrorPlaceholder from "./EmbedErrorPlaceholder";
14
17
  import { ResourceBox } from "../ResourceBox";
15
- import { jsx as _jsx } from "react/jsx-runtime";
18
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
16
19
  const StyledFigure = styled(Figure, {
17
20
  base: {
18
21
  "& iframe": {
@@ -21,6 +24,55 @@ const StyledFigure = styled(Figure, {
21
24
  }
22
25
  }
23
26
  });
27
+
28
+ // TODO: Move this to own component in UI? Use variant of existing?
29
+ const StyledSafeLink = styled(SafeLink, {
30
+ base: {
31
+ textDecoration: "underline",
32
+ textStyle: "label.large",
33
+ color: "text.link",
34
+ fontWeight: "bold",
35
+ _hover: {
36
+ textDecoration: "unset"
37
+ }
38
+ }
39
+ });
40
+ const LinkWrapper = styled("div", {
41
+ base: {
42
+ display: "flex",
43
+ alignItems: "center",
44
+ justifyContent: "space-between",
45
+ gap: "xsmall"
46
+ }
47
+ });
48
+ const TextWrapper = styled("div", {
49
+ base: {
50
+ display: "flex",
51
+ flexDirection: "column",
52
+ alignItems: "flex-start",
53
+ gap: "xxsmall"
54
+ }
55
+ });
56
+ const Wrapper = styled("div", {
57
+ base: {
58
+ display: "flex",
59
+ width: "100%",
60
+ gap: "small",
61
+ flexDirection: "column",
62
+ backgroundColor: "surface.brand.2.subtle",
63
+ borderRadius: "xxsmall",
64
+ padding: "medium",
65
+ border: "1px solid",
66
+ borderColor: "stroke.info"
67
+ }
68
+ });
69
+ const UrlText = styled(Text, {
70
+ base: {
71
+ textOverflow: "ellipsis",
72
+ whiteSpace: "nowrap",
73
+ overflow: "hidden"
74
+ }
75
+ });
24
76
  const ExternalEmbed = _ref => {
25
77
  let {
26
78
  embed
@@ -63,11 +115,35 @@ const ExternalEmbed = _ref => {
63
115
  })
64
116
  });
65
117
  }
118
+ if (embedData.type === "link") {
119
+ return /*#__PURE__*/_jsx(Figure, {
120
+ "data-embed-type": "external",
121
+ children: /*#__PURE__*/_jsxs(Wrapper, {
122
+ children: [/*#__PURE__*/_jsxs(LinkWrapper, {
123
+ children: [/*#__PURE__*/_jsxs(TextWrapper, {
124
+ children: [/*#__PURE__*/_jsx(StyledSafeLink, {
125
+ to: embedData.url,
126
+ unstyled: true,
127
+ css: linkOverlay.raw(),
128
+ children: embedData.title
129
+ }), /*#__PURE__*/_jsx(Text, {
130
+ textStyle: "label.medium",
131
+ children: embedData.caption
132
+ })]
133
+ }), /*#__PURE__*/_jsx(ArrowRightShortLine, {})]
134
+ }), /*#__PURE__*/_jsx(UrlText, {
135
+ textStyle: "label.medium",
136
+ color: "text.subtle",
137
+ children: embedData.url
138
+ })]
139
+ })
140
+ });
141
+ }
66
142
  return /*#__PURE__*/_jsx(StyledFigure, {
67
143
  "data-embed-type": "external",
68
144
  ref: figRef,
69
145
  dangerouslySetInnerHTML: {
70
- __html: data.oembed.html ?? ""
146
+ __html: data?.oembed?.html ?? ""
71
147
  }
72
148
  });
73
149
  };
@@ -6,8 +6,11 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _react = require("react");
8
8
  var _reactI18next = require("react-i18next");
9
+ var _icons = require("@ndla/icons");
9
10
  var _primitives = require("@ndla/primitives");
11
+ var _safelink = require("@ndla/safelink");
10
12
  var _jsx2 = require("@ndla/styled-system/jsx");
13
+ var _patterns = require("@ndla/styled-system/patterns");
11
14
  var _EmbedErrorPlaceholder = _interopRequireDefault(require("./EmbedErrorPlaceholder"));
12
15
  var _ResourceBox = require("../ResourceBox");
13
16
  var _jsxRuntime = require("react/jsx-runtime");
@@ -28,6 +31,55 @@ const StyledFigure = (0, _jsx2.styled)(_primitives.Figure, {
28
31
  }
29
32
  }
30
33
  });
34
+
35
+ // TODO: Move this to own component in UI? Use variant of existing?
36
+ const StyledSafeLink = (0, _jsx2.styled)(_safelink.SafeLink, {
37
+ base: {
38
+ textDecoration: "underline",
39
+ textStyle: "label.large",
40
+ color: "text.link",
41
+ fontWeight: "bold",
42
+ _hover: {
43
+ textDecoration: "unset"
44
+ }
45
+ }
46
+ });
47
+ const LinkWrapper = (0, _jsx2.styled)("div", {
48
+ base: {
49
+ display: "flex",
50
+ alignItems: "center",
51
+ justifyContent: "space-between",
52
+ gap: "xsmall"
53
+ }
54
+ });
55
+ const TextWrapper = (0, _jsx2.styled)("div", {
56
+ base: {
57
+ display: "flex",
58
+ flexDirection: "column",
59
+ alignItems: "flex-start",
60
+ gap: "xxsmall"
61
+ }
62
+ });
63
+ const Wrapper = (0, _jsx2.styled)("div", {
64
+ base: {
65
+ display: "flex",
66
+ width: "100%",
67
+ gap: "small",
68
+ flexDirection: "column",
69
+ backgroundColor: "surface.brand.2.subtle",
70
+ borderRadius: "xxsmall",
71
+ padding: "medium",
72
+ border: "1px solid",
73
+ borderColor: "stroke.info"
74
+ }
75
+ });
76
+ const UrlText = (0, _jsx2.styled)(_primitives.Text, {
77
+ base: {
78
+ textOverflow: "ellipsis",
79
+ whiteSpace: "nowrap",
80
+ overflow: "hidden"
81
+ }
82
+ });
31
83
  const ExternalEmbed = _ref => {
32
84
  let {
33
85
  embed
@@ -70,11 +122,35 @@ const ExternalEmbed = _ref => {
70
122
  })
71
123
  });
72
124
  }
125
+ if (embedData.type === "link") {
126
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.Figure, {
127
+ "data-embed-type": "external",
128
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(Wrapper, {
129
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(LinkWrapper, {
130
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(TextWrapper, {
131
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(StyledSafeLink, {
132
+ to: embedData.url,
133
+ unstyled: true,
134
+ css: _patterns.linkOverlay.raw(),
135
+ children: embedData.title
136
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.Text, {
137
+ textStyle: "label.medium",
138
+ children: embedData.caption
139
+ })]
140
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_icons.ArrowRightShortLine, {})]
141
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(UrlText, {
142
+ textStyle: "label.medium",
143
+ color: "text.subtle",
144
+ children: embedData.url
145
+ })]
146
+ })
147
+ });
148
+ }
73
149
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(StyledFigure, {
74
150
  "data-embed-type": "external",
75
151
  ref: figRef,
76
152
  dangerouslySetInnerHTML: {
77
- __html: data.oembed.html ?? ""
153
+ __html: data?.oembed?.html ?? ""
78
154
  }
79
155
  });
80
156
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ndla/ui",
3
- "version": "56.0.86-alpha.0",
3
+ "version": "56.0.87-alpha.0",
4
4
  "description": "UI component library for NDLA",
5
5
  "license": "GPL-3.0",
6
6
  "main": "lib/index.js",
@@ -52,11 +52,11 @@
52
52
  "devDependencies": {
53
53
  "@ndla/preset-panda": "^0.0.49",
54
54
  "@ndla/types-backend": "^1.0.1",
55
- "@ndla/types-embed": "^5.0.7-alpha.0",
55
+ "@ndla/types-embed": "^5.0.8-alpha.0",
56
56
  "@pandacss/dev": "^0.48.0"
57
57
  },
58
58
  "publishConfig": {
59
59
  "access": "public"
60
60
  },
61
- "gitHead": "ed6699652dec494cf9cf12712316ba5f4036438a"
61
+ "gitHead": "34ad8530b56efe3dc38052ccffaa6cd03d940d01"
62
62
  }
@@ -174,3 +174,14 @@ export const Fullscreen: StoryObj<typeof ExternalEmbed> = {
174
174
  },
175
175
  },
176
176
  };
177
+
178
+ export const Link: StoryObj<typeof ExternalEmbed> = {
179
+ args: {
180
+ embed: {
181
+ resource: "external",
182
+ status: "success",
183
+ embedData: { ...embedDataFullscreen, type: "link" },
184
+ data: opensInNewMetaData,
185
+ },
186
+ },
187
+ };
@@ -8,8 +8,11 @@
8
8
 
9
9
  import { useEffect, useRef } from "react";
10
10
  import { useTranslation } from "react-i18next";
11
- import { Figure } from "@ndla/primitives";
11
+ import { ArrowRightShortLine } from "@ndla/icons";
12
+ import { Figure, Text } from "@ndla/primitives";
13
+ import { SafeLink } from "@ndla/safelink";
12
14
  import { styled } from "@ndla/styled-system/jsx";
15
+ import { linkOverlay } from "@ndla/styled-system/patterns";
13
16
  import type { OembedMetaData } from "@ndla/types-embed";
14
17
  import EmbedErrorPlaceholder from "./EmbedErrorPlaceholder";
15
18
  import { ResourceBox } from "../ResourceBox";
@@ -27,6 +30,59 @@ const StyledFigure = styled(Figure, {
27
30
  },
28
31
  });
29
32
 
33
+ // TODO: Move this to own component in UI? Use variant of existing?
34
+ const StyledSafeLink = styled(SafeLink, {
35
+ base: {
36
+ textDecoration: "underline",
37
+ textStyle: "label.large",
38
+ color: "text.link",
39
+ fontWeight: "bold",
40
+ _hover: {
41
+ textDecoration: "unset",
42
+ },
43
+ },
44
+ });
45
+
46
+ const LinkWrapper = styled("div", {
47
+ base: {
48
+ display: "flex",
49
+ alignItems: "center",
50
+ justifyContent: "space-between",
51
+ gap: "xsmall",
52
+ },
53
+ });
54
+
55
+ const TextWrapper = styled("div", {
56
+ base: {
57
+ display: "flex",
58
+ flexDirection: "column",
59
+ alignItems: "flex-start",
60
+ gap: "xxsmall",
61
+ },
62
+ });
63
+
64
+ const Wrapper = styled("div", {
65
+ base: {
66
+ display: "flex",
67
+ width: "100%",
68
+ gap: "small",
69
+ flexDirection: "column",
70
+ backgroundColor: "surface.brand.2.subtle",
71
+ borderRadius: "xxsmall",
72
+ padding: "medium",
73
+ border: "1px solid",
74
+ borderColor: "stroke.info",
75
+ },
76
+ });
77
+
78
+ const UrlText = styled(Text, {
79
+ base: {
80
+ textOverflow: "ellipsis",
81
+ whiteSpace: "nowrap",
82
+ overflow: "hidden",
83
+ },
84
+ });
85
+
30
86
  const ExternalEmbed = ({ embed }: Props) => {
31
87
  const { t } = useTranslation();
32
88
  const figRef = useRef<HTMLElement>(null);
@@ -65,13 +121,33 @@ const ExternalEmbed = ({ embed }: Props) => {
65
121
  );
66
122
  }
67
123
 
124
+ if (embedData.type === "link") {
125
+ return (
126
+ <Figure data-embed-type="external">
127
+ <Wrapper>
128
+ <LinkWrapper>
129
+ <TextWrapper>
130
+ <StyledSafeLink to={embedData.url} unstyled css={linkOverlay.raw()}>
131
+ {embedData.title}
132
+ </StyledSafeLink>
133
+ <Text textStyle="label.medium">{embedData.caption}</Text>
134
+ </TextWrapper>
135
+ <ArrowRightShortLine />
136
+ </LinkWrapper>
137
+ <UrlText textStyle="label.medium" color="text.subtle">
138
+ {embedData.url}
139
+ </UrlText>
140
+ </Wrapper>
141
+ </Figure>
142
+ );
143
+ }
144
+
68
145
  return (
69
146
  <StyledFigure
70
147
  data-embed-type="external"
71
148
  ref={figRef}
72
- dangerouslySetInnerHTML={{ __html: data.oembed.html ?? "" }}
149
+ dangerouslySetInnerHTML={{ __html: data?.oembed?.html ?? "" }}
73
150
  />
74
151
  );
75
152
  };
76
-
77
153
  export default ExternalEmbed;