@ndla/ui 56.0.19-alpha.0 → 56.0.21-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 (44) hide show
  1. package/dist/panda.buildinfo.json +6 -10
  2. package/dist/styles.css +8 -25
  3. package/es/Concept/Concept.js +3 -1
  4. package/es/Embed/ConceptEmbed.js +4 -1
  5. package/es/Embed/ImageEmbed.js +2 -38
  6. package/es/TagSelector/TagSelector.js +3 -3
  7. package/es/i18n/useComponentTranslations.js +12 -11
  8. package/es/locale/messages-en.js +14 -10
  9. package/es/locale/messages-nb.js +14 -10
  10. package/es/locale/messages-nn.js +14 -10
  11. package/es/locale/messages-se.js +14 -10
  12. package/es/locale/messages-sma.js +14 -10
  13. package/es/styles.css +8 -25
  14. package/lib/Concept/Concept.d.ts +1 -0
  15. package/lib/Concept/Concept.js +3 -1
  16. package/lib/Embed/ConceptEmbed.d.ts +2 -1
  17. package/lib/Embed/ConceptEmbed.js +4 -1
  18. package/lib/Embed/ImageEmbed.js +2 -38
  19. package/lib/TagSelector/TagSelector.js +3 -3
  20. package/lib/i18n/useComponentTranslations.d.ts +7 -7
  21. package/lib/i18n/useComponentTranslations.js +12 -11
  22. package/lib/locale/messages-en.d.ts +8 -4
  23. package/lib/locale/messages-en.js +14 -10
  24. package/lib/locale/messages-nb.d.ts +8 -4
  25. package/lib/locale/messages-nb.js +14 -10
  26. package/lib/locale/messages-nn.d.ts +8 -4
  27. package/lib/locale/messages-nn.js +14 -10
  28. package/lib/locale/messages-se.d.ts +8 -4
  29. package/lib/locale/messages-se.js +14 -10
  30. package/lib/locale/messages-sma.d.ts +8 -4
  31. package/lib/locale/messages-sma.js +14 -10
  32. package/lib/styles.css +8 -25
  33. package/package.json +7 -7
  34. package/src/Concept/Concept.tsx +3 -2
  35. package/src/Embed/ConceptEmbed.tsx +4 -1
  36. package/src/Embed/ImageEmbed.stories.tsx +17 -1
  37. package/src/Embed/ImageEmbed.tsx +2 -44
  38. package/src/TagSelector/TagSelector.tsx +4 -8
  39. package/src/i18n/useComponentTranslations.ts +19 -18
  40. package/src/locale/messages-en.ts +11 -7
  41. package/src/locale/messages-nb.ts +11 -7
  42. package/src/locale/messages-nn.ts +11 -7
  43. package/src/locale/messages-se.ts +11 -7
  44. package/src/locale/messages-sma.ts +11 -7
@@ -986,6 +986,8 @@ declare const messages: {
986
986
  posts: string;
987
987
  posts_plural: string;
988
988
  subcategory: string;
989
+ votes: string;
990
+ votes_plural: string;
989
991
  };
990
992
  publish: string;
991
993
  cancel: {
@@ -1048,6 +1050,8 @@ declare const messages: {
1048
1050
  unlock: string;
1049
1051
  lockDescription: string;
1050
1052
  unlockDescription: string;
1053
+ votes: string;
1054
+ votes_plural: string;
1051
1055
  };
1052
1056
  posts: {
1053
1057
  title: string;
@@ -1425,18 +1429,18 @@ declare const messages: {
1425
1429
  page: string;
1426
1430
  };
1427
1431
  imageSearch: {
1428
- close: string;
1429
1432
  searchPlaceholder: string;
1430
1433
  searchButtonTitle: string;
1431
- useImageTitle: string;
1432
- checkboxLabel: string;
1433
- imageMetadata: {
1434
+ imagePreview: {
1434
1435
  creatorsLabel: string;
1435
1436
  license: string;
1436
1437
  caption: string;
1437
1438
  altText: string;
1438
1439
  modelRelease: string;
1439
1440
  tags: string;
1441
+ checkboxLabel: string;
1442
+ close: string;
1443
+ useImageTitle: string;
1440
1444
  };
1441
1445
  };
1442
1446
  audioSearch: {
@@ -1002,7 +1002,9 @@ const messages = {
1002
1002
  title: "Kategorier",
1003
1003
  posts: "innlegg",
1004
1004
  posts_plural: "innlegg",
1005
- subcategory: "Tema"
1005
+ subcategory: "Tema",
1006
+ votes: "reaksjon",
1007
+ votes_plural: "reaksjoner"
1006
1008
  },
1007
1009
  publish: "Publiser",
1008
1010
  cancel: {
@@ -1064,7 +1066,9 @@ const messages = {
1064
1066
  locked: "Lås innlegg",
1065
1067
  unlock: "Lås opp innlegg",
1066
1068
  lockDescription: "Vil du låse dette innlegget? Dette vil gjøre at innlegget ikke kan få flere kommentarer, og vil vises som låst.",
1067
- unlockDescription: "Vil du låse opp dette innlegget? Dette vil gjøre at innlegget kan få flere kommentarer."
1069
+ unlockDescription: "Vil du låse opp dette innlegget? Dette vil gjøre at innlegget kan få flere kommentarer.",
1070
+ votes: "reaksjon",
1071
+ votes_plural: "reaksjoner"
1068
1072
  },
1069
1073
  posts: {
1070
1074
  title: "Innlegg",
@@ -1093,12 +1097,12 @@ const messages = {
1093
1097
  maxLength: "Maksimal lengde for tekstfeltet er nådd",
1094
1098
  error: "Feltet er påkrevd"
1095
1099
  },
1096
- bottomText: "Savner du en kategori? Gi vår moderator beskjed ",
1100
+ bottomText: "Savner du en kategori? Du kan be om nye kategorier. Bruk 'Spør NDLA' eller send en epost til ",
1097
1101
  moderatorEmail: "moderator@ndla.no",
1098
1102
  notification: {
1099
1103
  title: "Varslinger",
1100
1104
  showAll: "Se alle varslinger",
1101
- description: "Velkommen inn i arenaen for lærere i videregående opplæring! Dette er <em>din</em> arena: et faglig møtested for diskusjon, inspirasjon, deling og utviklende samarbeid.",
1105
+ description: "Velkommen til NDLAs Arena. Her kan du diskutere, dele og samarbeide med andre lærere fra hele Norge.",
1102
1106
  myNotification: "Mine varsler",
1103
1107
  markAll: "Merk alle som lest",
1104
1108
  subscribe: "Du får nå varsling om nye svar på dette innlegget",
@@ -1111,7 +1115,7 @@ const messages = {
1111
1115
  },
1112
1116
  topicsBy: "Innlegg av",
1113
1117
  admin: {
1114
- title: "Arena administrator",
1118
+ title: "Arena admin",
1115
1119
  description: "Verktøy for å moderere og administrere arenaen.",
1116
1120
  administrate: "Administrer",
1117
1121
  category: {
@@ -1476,18 +1480,18 @@ const messages = {
1476
1480
  page: "Side {{page}}"
1477
1481
  },
1478
1482
  imageSearch: {
1479
- close: "Lukk",
1480
1483
  searchPlaceholder: "Søk i bilder",
1481
1484
  searchButtonTitle: "Søk",
1482
- useImageTitle: "Bruk bildet",
1483
- checkboxLabel: "Sett som metabilde",
1484
- imageMetadata: {
1485
+ imagePreview: {
1485
1486
  creatorsLabel: "Bilde",
1486
1487
  license: "Lisens",
1487
1488
  caption: "Bildetekst",
1488
1489
  altText: "Alt-tekst",
1489
1490
  modelRelease: "Modellklarert",
1490
- tags: "Emneknagger"
1491
+ tags: "Emneknagger",
1492
+ checkboxLabel: "Sett som metabilde",
1493
+ close: "Lukk",
1494
+ useImageTitle: "Bruk bildet"
1491
1495
  }
1492
1496
  },
1493
1497
  audioSearch: {
@@ -986,6 +986,8 @@ declare const messages: {
986
986
  posts: string;
987
987
  posts_plural: string;
988
988
  subcategory: string;
989
+ votes: string;
990
+ votes_plural: string;
989
991
  };
990
992
  publish: string;
991
993
  cancel: {
@@ -1048,6 +1050,8 @@ declare const messages: {
1048
1050
  unlock: string;
1049
1051
  lockDescription: string;
1050
1052
  unlockDescription: string;
1053
+ votes: string;
1054
+ votes_plural: string;
1051
1055
  };
1052
1056
  posts: {
1053
1057
  title: string;
@@ -1425,18 +1429,18 @@ declare const messages: {
1425
1429
  page: string;
1426
1430
  };
1427
1431
  imageSearch: {
1428
- close: string;
1429
1432
  searchPlaceholder: string;
1430
1433
  searchButtonTitle: string;
1431
- useImageTitle: string;
1432
- checkboxLabel: string;
1433
- imageMetadata: {
1434
+ imagePreview: {
1434
1435
  creatorsLabel: string;
1435
1436
  license: string;
1436
1437
  caption: string;
1437
1438
  altText: string;
1438
1439
  modelRelease: string;
1439
1440
  tags: string;
1441
+ checkboxLabel: string;
1442
+ close: string;
1443
+ useImageTitle: string;
1440
1444
  };
1441
1445
  };
1442
1446
  audioSearch: {
@@ -1002,7 +1002,9 @@ const messages = {
1002
1002
  title: "Kategorier",
1003
1003
  posts: "innlegg",
1004
1004
  posts_plural: "innlegg",
1005
- subcategory: "Tema"
1005
+ subcategory: "Tema",
1006
+ votes: "reaksjon",
1007
+ votes_plural: "reaksjoner"
1006
1008
  },
1007
1009
  publish: "Publiser",
1008
1010
  cancel: {
@@ -1064,7 +1066,9 @@ const messages = {
1064
1066
  locked: "Lås innlegg",
1065
1067
  unlock: "Lås opp innlegg",
1066
1068
  lockDescription: "Vil du låse dette innlegget? Dette vil gjøre at innlegget ikke kan få flere kommentarer, og vil vises som låst.",
1067
- unlockDescription: "Vil du låse opp dette innlegget? Dette vil gjøre at innlegget kan få flere kommentarer."
1069
+ unlockDescription: "Vil du låse opp dette innlegget? Dette vil gjøre at innlegget kan få flere kommentarer.",
1070
+ votes: "reaksjon",
1071
+ votes_plural: "reaksjoner"
1068
1072
  },
1069
1073
  posts: {
1070
1074
  title: "Innlegg",
@@ -1093,12 +1097,12 @@ const messages = {
1093
1097
  maxLength: "Maksimal lengde for tekstfeltet er nådd",
1094
1098
  error: "Feltet er påkrevd"
1095
1099
  },
1096
- bottomText: "Savner du en kategori? Gi vår moderator beskjed ",
1100
+ bottomText: "Savner du en kategori? Du kan be om nye kategorier. Bruk 'Spør NDLA' eller send en epost til ",
1097
1101
  moderatorEmail: "moderator@ndla.no",
1098
1102
  notification: {
1099
1103
  title: "Varslinger",
1100
1104
  showAll: "Se alle varslinger",
1101
- description: "Velkommen inn i arenaen for lærere i videregående opplæring! Dette er <em>din</em> arena: et faglig møtested for diskusjon, inspirasjon, deling og utviklende samarbeid.",
1105
+ description: "Velkommen til NDLAs Arena. Her kan du diskutere, dele og samarbeide med andre lærere fra hele Norge.",
1102
1106
  myNotification: "Mine varsler",
1103
1107
  markAll: "Merk alle som lest",
1104
1108
  subscribe: "Du får nå varsling om nye svar på dette innlegget",
@@ -1111,7 +1115,7 @@ const messages = {
1111
1115
  },
1112
1116
  topicsBy: "Innlegg av",
1113
1117
  admin: {
1114
- title: "Arena administrator",
1118
+ title: "Arena admin",
1115
1119
  description: "Verktøy for å moderere og administrere arenaen.",
1116
1120
  administrate: "Administrer",
1117
1121
  category: {
@@ -1476,18 +1480,18 @@ const messages = {
1476
1480
  page: "Side {{page}}"
1477
1481
  },
1478
1482
  imageSearch: {
1479
- close: "Lukk",
1480
1483
  searchPlaceholder: "Søk i bilder",
1481
1484
  searchButtonTitle: "Søk",
1482
- useImageTitle: "Bruk bildet",
1483
- checkboxLabel: "Sett som metabilde",
1484
- imageMetadata: {
1485
+ imagePreview: {
1485
1486
  creatorsLabel: "Bilde",
1486
1487
  license: "Lisens",
1487
1488
  caption: "Bildetekst",
1488
1489
  altText: "Alt-tekst",
1489
1490
  modelRelease: "Modellklarert",
1490
- tags: "Emneknagger"
1491
+ tags: "Emneknagger",
1492
+ checkboxLabel: "Sett som metabilde",
1493
+ close: "Lukk",
1494
+ useImageTitle: "Bruk bildet"
1491
1495
  }
1492
1496
  },
1493
1497
  audioSearch: {
package/lib/styles.css CHANGED
@@ -458,11 +458,6 @@
458
458
  border-bottom: 0;
459
459
  }
460
460
 
461
- .bg_background\.default\/20 {
462
- --mix-background: color-mix(in srgb, var(--colors-background-default) 20%, transparent);
463
- background: var(--mix-background, var(--colors-background-default));
464
- }
465
-
466
461
  .p_0 {
467
462
  padding: 0;
468
463
  }
@@ -742,12 +737,16 @@
742
737
  border-bottom-right-radius: 0;
743
738
  }
744
739
 
745
- .bottom_0 {
746
- bottom: 0;
740
+ .top_xsmall {
741
+ top: var(--spacing-xsmall);
747
742
  }
748
743
 
749
- .right_0 {
750
- right: 0;
744
+ .right_xsmall {
745
+ right: var(--spacing-xsmall);
746
+ }
747
+
748
+ .bd-c_background\.default {
749
+ border-color: var(--colors-background-default);
751
750
  }
752
751
 
753
752
  .trs-prop_transform\,_background-color\,_color {
@@ -765,18 +764,6 @@
765
764
  transition-timing-function: ease-out;
766
765
  }
767
766
 
768
- .top_xsmall {
769
- top: var(--spacing-xsmall);
770
- }
771
-
772
- .right_xsmall {
773
- right: var(--spacing-xsmall);
774
- }
775
-
776
- .bd-c_background\.default {
777
- border-color: var(--colors-background-default);
778
- }
779
-
780
767
  .bg-c_surface\.action {
781
768
  background-color: var(--colors-surface-action);
782
769
  }
@@ -1092,10 +1079,6 @@
1092
1079
  margin-inline-start: var(--spacing-1);
1093
1080
  }
1094
1081
 
1095
- .\[\&_svg\]\:fill_primary svg {
1096
- fill: var(--colors-primary);
1097
- }
1098
-
1099
1082
  .\[\&_a\]\:c_text\.strong a {
1100
1083
  color: var(--colors-text-strong);
1101
1084
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ndla/ui",
3
- "version": "56.0.19-alpha.0",
3
+ "version": "56.0.21-alpha.0",
4
4
  "description": "UI component library for NDLA",
5
5
  "license": "GPL-3.0",
6
6
  "main": "lib/index.js",
@@ -34,11 +34,11 @@
34
34
  ],
35
35
  "dependencies": {
36
36
  "@ndla/core": "^5.0.2",
37
- "@ndla/icons": "^8.0.13-alpha.0",
37
+ "@ndla/icons": "^8.0.15-alpha.0",
38
38
  "@ndla/licenses": "^8.0.2-alpha.0",
39
- "@ndla/primitives": "^1.0.17-alpha.0",
40
- "@ndla/safelink": "^7.0.17-alpha.0",
41
- "@ndla/styled-system": "^0.0.15",
39
+ "@ndla/primitives": "^1.0.19-alpha.0",
40
+ "@ndla/safelink": "^7.0.19-alpha.0",
41
+ "@ndla/styled-system": "^0.0.17",
42
42
  "@ndla/util": "^4.1.0",
43
43
  "html-react-parser": "^5.1.8",
44
44
  "i18next-browser-languagedetector": "^7.1.0"
@@ -53,7 +53,7 @@
53
53
  "react-router-dom": "> 6.0.0"
54
54
  },
55
55
  "devDependencies": {
56
- "@ndla/preset-panda": "^0.0.23",
56
+ "@ndla/preset-panda": "^0.0.25",
57
57
  "@ndla/types-backend": "^0.2.86",
58
58
  "@ndla/types-embed": "^5.0.1-alpha.0",
59
59
  "@pandacss/dev": "^0.45.2",
@@ -66,5 +66,5 @@
66
66
  "publishConfig": {
67
67
  "access": "public"
68
68
  },
69
- "gitHead": "58687255a5be26e49b6a21d830cf0af5be37b9fa"
69
+ "gitHead": "4271f1708f835715edca5fd10f6ee4b182a207b4"
70
70
  }
@@ -22,6 +22,7 @@ export interface ConceptProps extends ComponentPropsWithRef<"figure"> {
22
22
  title?: string;
23
23
  children?: ReactNode;
24
24
  source?: string;
25
+ previewAlt?: boolean;
25
26
  }
26
27
 
27
28
  const StyledFigure = styled(Figure, {
@@ -45,7 +46,7 @@ const ContentWrapper = styled("div", {
45
46
  // TODO: Figure out if we need to support headerButtons.
46
47
 
47
48
  export const Concept = forwardRef<HTMLElement, ConceptProps>(
48
- ({ copyright, visualElement, lang, children, title, source, ...rest }, ref) => {
49
+ ({ copyright, visualElement, lang, children, title, source, previewAlt, ...rest }, ref) => {
49
50
  const licenseProps = licenseAttributes(copyright?.license?.license, lang, source);
50
51
 
51
52
  return (
@@ -60,7 +61,7 @@ export const Concept = forwardRef<HTMLElement, ConceptProps>(
60
61
  {children}
61
62
  </ContentWrapper>
62
63
  {visualElement?.resource === "image" ? (
63
- <ImageEmbed embed={visualElement} lang={lang} />
64
+ <ImageEmbed embed={visualElement} lang={lang} previewAlt={previewAlt} />
64
65
  ) : visualElement?.resource === "brightcove" ? (
65
66
  <BrightcoveEmbed embed={visualElement} />
66
67
  ) : visualElement?.resource === "h5p" ? (
@@ -21,6 +21,7 @@ import { Concept, ConceptProps } from "../Concept/Concept";
21
21
  interface BaseProps {
22
22
  renderContext?: RenderContext;
23
23
  lang?: string;
24
+ previewAlt?: boolean;
24
25
  }
25
26
 
26
27
  interface Props extends BaseProps {
@@ -35,7 +36,7 @@ const StyledPopoverContent = styled(PopoverContent, {
35
36
  },
36
37
  });
37
38
 
38
- export const ConceptEmbed = ({ embed, renderContext, lang }: Props) => {
39
+ export const ConceptEmbed = ({ embed, renderContext, lang, previewAlt }: Props) => {
39
40
  const parsedContent = useMemo(() => {
40
41
  if (embed.status === "error" || !embed.data.concept.content) return undefined;
41
42
  return parse(embed.data.concept.content.htmlContent);
@@ -58,6 +59,7 @@ export const ConceptEmbed = ({ embed, renderContext, lang }: Props) => {
58
59
  if (embed.embedData.type === "inline") {
59
60
  return (
60
61
  <InlineConcept
62
+ previewAlt={previewAlt}
61
63
  linkText={embed.embedData.linkText}
62
64
  copyright={concept.copyright}
63
65
  visualElement={visualElement}
@@ -72,6 +74,7 @@ export const ConceptEmbed = ({ embed, renderContext, lang }: Props) => {
72
74
 
73
75
  return (
74
76
  <BlockConcept
77
+ previewAlt={previewAlt}
75
78
  copyright={concept.copyright}
76
79
  visualElement={visualElement}
77
80
  lang={lang}
@@ -139,7 +139,23 @@ export const HiddenByline: StoryObj<typeof ImageEmbed> = {
139
139
  status: "success",
140
140
  embedData: {
141
141
  ...embedData,
142
- size: "full-hide-byline",
142
+ size: "full",
143
+ hideByline: "true",
144
+ },
145
+ data: metaData,
146
+ },
147
+ },
148
+ };
149
+
150
+ export const HiddenCaption: StoryObj<typeof ImageEmbed> = {
151
+ args: {
152
+ embed: {
153
+ resource: "image",
154
+ status: "success",
155
+ embedData: {
156
+ ...embedData,
157
+ size: "full",
158
+ hideCaption: "true",
143
159
  },
144
160
  data: metaData,
145
161
  },
@@ -10,7 +10,6 @@ import parse from "html-react-parser";
10
10
  import { ReactNode, useMemo, useState } from "react";
11
11
  import { useTranslation } from "react-i18next";
12
12
  import { AddLine } from "@ndla/icons/action";
13
- import { ArrowDownShortLine, ArrowUpShortLine } from "@ndla/icons/common";
14
13
  import { Figure, FigureSize, FigureVariantProps, Image } from "@ndla/primitives";
15
14
  import { styled } from "@ndla/styled-system/jsx";
16
15
  import { ImageEmbedData, ImageMetaData } from "@ndla/types-embed";
@@ -157,33 +156,6 @@ const StyledFigure = styled(Figure, {
157
156
  },
158
157
  });
159
158
 
160
- const BylineButton = styled(
161
- "button",
162
- {
163
- base: {
164
- cursor: "pointer",
165
- position: "absolute",
166
- zIndex: "base",
167
- bottom: "0",
168
- right: "0",
169
- paddingBlock: "xsmall",
170
- paddingInline: "xsmall",
171
- transitionProperty: "transform, background-color, color",
172
- transitionDuration: "normal",
173
- transitionTimingFunction: "ease-out",
174
- background: "background.default/20",
175
- border: "0",
176
- "& svg": {
177
- transitionProperty: "transform",
178
- transitionDuration: "normal",
179
- transitionTimingFunction: "ease-out",
180
- fill: "primary",
181
- },
182
- },
183
- },
184
- { defaultProps: { type: "button" } },
185
- );
186
-
187
159
  const ExpandButton = styled(
188
160
  "button",
189
161
  {
@@ -217,7 +189,6 @@ const ExpandButton = styled(
217
189
  );
218
190
 
219
191
  const ImageEmbed = ({ embed, previewAlt, lang, renderContext = "article", children }: Props) => {
220
- const [isBylineHidden, setIsBylineHidden] = useState(hideByline(embed.embedData));
221
192
  const [imageSizes, setImageSizes] = useState<string | undefined>(undefined);
222
193
  const figureProps = getFigureProps(embed.embedData.size, embed.embedData.align);
223
194
  const { t } = useTranslation();
@@ -279,21 +250,12 @@ const ImageEmbed = ({ embed, previewAlt, lang, renderContext = "article", childr
279
250
  <AddLine />
280
251
  </ExpandButton>
281
252
  )}
282
- {(embedData.size?.endsWith("-hide-byline") || embedData.hideByline === "true") && (
283
- <BylineButton
284
- data-byline-button=""
285
- aria-label={t(`license.images.itemImage.${isBylineHidden ? "expandByline" : "minimizeByline"}`)}
286
- onClick={() => setIsBylineHidden((p) => !p)}
287
- >
288
- {isBylineHidden ? <ArrowDownShortLine /> : <ArrowUpShortLine />}
289
- </BylineButton>
290
- )}
291
253
  </ImageWrapper>
292
- {isBylineHidden ? null : (
254
+ {embedData.hideByline === "true" ? null : (
293
255
  <EmbedByline
294
256
  type="image"
295
257
  copyright={data.copyright}
296
- description={parsedDescription}
258
+ description={embedData.hideCaption === "true" ? "" : parsedDescription}
297
259
  visibleAlt={previewAlt ? embed.embedData.alt : ""}
298
260
  />
299
261
  )}
@@ -301,8 +263,4 @@ const ImageEmbed = ({ embed, previewAlt, lang, renderContext = "article", childr
301
263
  );
302
264
  };
303
265
 
304
- const hideByline = (embed: ImageEmbedData): boolean => {
305
- return (!!embed.size && embed.size.endsWith("-hide-byline")) || embed.hideByline === "true";
306
- };
307
-
308
266
  export default ImageEmbed;
@@ -108,10 +108,8 @@ export const TagSelectorTrigger = ComboboxTrigger;
108
108
 
109
109
  export const TagSelectorControl = forwardRef<HTMLDivElement, TagSelectorControlProps>(({ children, ...props }, ref) => {
110
110
  return (
111
- <ComboboxControl asChild>
112
- <TagsInputControl {...props} ref={ref}>
113
- {children}
114
- </TagsInputControl>
111
+ <ComboboxControl ref={ref} asChild>
112
+ <TagsInputControl {...props}>{children}</TagsInputControl>
115
113
  </ComboboxControl>
116
114
  );
117
115
  });
@@ -126,7 +124,7 @@ export const TagSelectorInputBase = forwardRef<HTMLInputElement, TagSelectorInpu
126
124
  const tagsApi = useTagsInputContext();
127
125
 
128
126
  return (
129
- <ComboboxInput asChild>
127
+ <ComboboxInput ref={ref} asChild>
130
128
  <TagsInputInput
131
129
  {...props}
132
130
  onKeyDown={(event) => {
@@ -134,7 +132,6 @@ export const TagSelectorInputBase = forwardRef<HTMLInputElement, TagSelectorInpu
134
132
  tagsApi.addValue(tagsApi.inputValue);
135
133
  }
136
134
  }}
137
- ref={ref}
138
135
  >
139
136
  {children}
140
137
  </TagsInputInput>
@@ -159,7 +156,7 @@ export const TagSelectorInput = forwardRef<HTMLInputElement, TagSelectorInputPro
159
156
  <TagsInputItemInput />
160
157
  </TagsInputItem>
161
158
  ))}
162
- <ComboboxInput asChild>
159
+ <ComboboxInput ref={ref} asChild>
163
160
  <TagsInputInput
164
161
  {...props}
165
162
  onKeyDown={(event) => {
@@ -167,7 +164,6 @@ export const TagSelectorInput = forwardRef<HTMLInputElement, TagSelectorInputPro
167
164
  tagsApi.addValue(tagsApi.inputValue);
168
165
  }
169
166
  }}
170
- ref={ref}
171
167
  >
172
168
  {children}
173
169
  </TagsInputInput>
@@ -84,24 +84,24 @@ interface AudioSearchTranslations {
84
84
  paginationTranslations: PaginationRootProps["translations"];
85
85
  }
86
86
 
87
- interface MetadataTranslations {
87
+ export interface PreviewTranslations {
88
88
  creatorsLabel: string;
89
89
  license: string;
90
90
  caption: string;
91
91
  altText: string;
92
92
  modelRelease: string;
93
93
  tags: string;
94
+ close: string;
95
+ checkboxLabel?: string;
96
+ missingTitleFallback?: string;
97
+ useImageTitle: string;
94
98
  }
95
99
 
96
- interface ImageSearchTranslations {
100
+ export interface ImageSearchTranslations {
97
101
  searchPlaceholder: string;
98
102
  searchButtonTitle: string;
99
- useImageTitle: string;
100
- close: string;
101
- imageMetadata: MetadataTranslations;
103
+ imagePreview: PreviewTranslations;
102
104
  paginationTranslations: PaginationRootProps["translations"];
103
- missingTitleFallback?: string;
104
- checkboxLabel?: string;
105
105
  }
106
106
 
107
107
  export const useImageSearchTranslations = (
@@ -110,21 +110,22 @@ export const useImageSearchTranslations = (
110
110
  const { t } = useTranslation("translation", { keyPrefix: "component.imageSearch" });
111
111
  const paginationTranslations = usePaginationTranslations();
112
112
 
113
- const { imageMetadata, paginationTranslations: fallbackPaginationTranslations, ...remaining } = translations;
113
+ const { imagePreview, paginationTranslations: fallbackPaginationTranslations, ...remaining } = translations;
114
114
 
115
115
  return {
116
- close: t("close"),
117
116
  searchPlaceholder: t("searchPlaceholder"),
118
117
  searchButtonTitle: t("searchButtonTitle"),
119
- useImageTitle: t("useImageTitle"),
120
- imageMetadata: {
121
- creatorsLabel: t("imageMetadata.creatorsLabel"),
122
- license: t("imageMetadata.license"),
123
- caption: t("imageMetadata.caption"),
124
- altText: t("imageMetadata.altText"),
125
- modelRelease: t("imageMetadata.modelRelease"),
126
- tags: t("imageMetadata.tags"),
127
- ...imageMetadata,
118
+ imagePreview: {
119
+ creatorsLabel: t("imagePreview.creatorsLabel"),
120
+ license: t("imagePreview.license"),
121
+ caption: t("imagePreview.caption"),
122
+ altText: t("imagePreview.altText"),
123
+ modelRelease: t("imagePreview.modelRelease"),
124
+ tags: t("imagePreview.tags"),
125
+ close: t("close"),
126
+ checkboxLabel: t("imagePreview.checkboxLabel"),
127
+ useImageTitle: t("imagePreview.useImageTitle"),
128
+ ...imagePreview,
128
129
  },
129
130
  paginationTranslations: { ...paginationTranslations, ...fallbackPaginationTranslations },
130
131
  ...remaining,
@@ -1014,6 +1014,8 @@ const messages = {
1014
1014
  posts: "post",
1015
1015
  posts_plural: "posts",
1016
1016
  subcategory: "Subcategories",
1017
+ votes: "reaction",
1018
+ votes_plural: "reactions",
1017
1019
  },
1018
1020
  cancel: {
1019
1021
  title: {
@@ -1077,6 +1079,8 @@ const messages = {
1077
1079
  unlock: "Unlock topic",
1078
1080
  lockDescription: "Do you want do lock this topic? This will prevent this topic from getting more posts.",
1079
1081
  unlockDescription: "Do you want do unlock this topic? This will prevent this topic from getting more posts.",
1082
+ votes: "reaction",
1083
+ votes_plural: "reactions",
1080
1084
  },
1081
1085
  posts: {
1082
1086
  title: "Posts",
@@ -1107,13 +1111,13 @@ const messages = {
1107
1111
  maxLength: "The maximum length for the text field is reached",
1108
1112
  error: "The field is required",
1109
1113
  },
1110
- bottomText: "Are you missing a category? Let our moderator know at ",
1114
+ bottomText: "Are you missing a category? You can request new categories. Use 'Ask NDLA' or send an email to ",
1111
1115
  moderatorEmail: "moderator@ndla.no",
1112
1116
  notification: {
1113
1117
  title: "Notifications",
1114
1118
  showAll: "View all notifications",
1115
1119
  description:
1116
- "Welcome to the arena for teachers in upper secondary education. This is <em>your</em> arena: a professional meeting place for discussion, inspiration, sharing, development, and collaboration.",
1120
+ "Welcome to NDLAs Arena. Here, you can discuss, share and cooperate with other teachers from all over Norway.",
1117
1121
  myNotification: "My notifications",
1118
1122
  markAll: "Mark all as read",
1119
1123
  subscribe: "You will now be notified of new replies to this topic",
@@ -1126,7 +1130,7 @@ const messages = {
1126
1130
  },
1127
1131
  topicsBy: "Topics by",
1128
1132
  admin: {
1129
- title: "Arena administrator",
1133
+ title: "Arena admin",
1130
1134
  description: "Tools to moderate and administer the arena.",
1131
1135
  administrate: "Administrate",
1132
1136
  category: {
@@ -1502,18 +1506,18 @@ const messages = {
1502
1506
  page: "Page {{page}}",
1503
1507
  },
1504
1508
  imageSearch: {
1505
- close: "Close",
1506
1509
  searchPlaceholder: "Search images",
1507
1510
  searchButtonTitle: "Search",
1508
- useImageTitle: "Use image",
1509
- checkboxLabel: "Set as meta image",
1510
- imageMetadata: {
1511
+ imagePreview: {
1511
1512
  creatorsLabel: "Image",
1512
1513
  license: "License",
1513
1514
  caption: "Caption",
1514
1515
  altText: "Alt-text",
1515
1516
  modelRelease: "Model released",
1516
1517
  tags: "Tags",
1518
+ checkboxLabel: "Set as meta image",
1519
+ close: "Close",
1520
+ useImageTitle: "Use image",
1517
1521
  },
1518
1522
  },
1519
1523
  audioSearch: {