@ndla/ui 55.0.10-alpha.0 → 55.0.11-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.
- package/es/index.js +0 -2
- package/lib/index.d.ts +0 -3
- package/lib/index.js +0 -20
- package/package.json +8 -8
- package/src/index.ts +0 -3
- package/es/MyNdla/Resource/Folder.js +0 -135
- package/es/MyNdla/Resource/index.js +0 -10
- package/es/MyNdla/index.js +0 -10
- package/es/Resource/BlockResource.js +0 -204
- package/es/Resource/ListResource.js +0 -235
- package/es/Resource/index.js +0 -10
- package/es/Resource/resourceComponents.js +0 -179
- package/es/Resource/storyComponents.js +0 -64
- package/lib/MyNdla/Resource/Folder.d.ts +0 -24
- package/lib/MyNdla/Resource/Folder.js +0 -142
- package/lib/MyNdla/Resource/index.d.ts +0 -9
- package/lib/MyNdla/Resource/index.js +0 -13
- package/lib/MyNdla/index.d.ts +0 -9
- package/lib/MyNdla/index.js +0 -13
- package/lib/Resource/BlockResource.d.ts +0 -28
- package/lib/Resource/BlockResource.js +0 -208
- package/lib/Resource/ListResource.d.ts +0 -28
- package/lib/Resource/ListResource.js +0 -239
- package/lib/Resource/index.d.ts +0 -11
- package/lib/Resource/index.js +0 -20
- package/lib/Resource/resourceComponents.d.ts +0 -43
- package/lib/Resource/resourceComponents.js +0 -188
- package/lib/Resource/storyComponents.d.ts +0 -12
- package/lib/Resource/storyComponents.js +0 -71
- package/src/MyNdla/Resource/Folder.stories.tsx +0 -87
- package/src/MyNdla/Resource/Folder.tsx +0 -228
- package/src/MyNdla/Resource/index.ts +0 -10
- package/src/MyNdla/index.ts +0 -10
- package/src/Resource/BlockResource.stories.tsx +0 -98
- package/src/Resource/BlockResource.tsx +0 -212
- package/src/Resource/ListResource.stories.tsx +0 -99
- package/src/Resource/ListResource.tsx +0 -273
- package/src/Resource/index.ts +0 -12
- package/src/Resource/resourceComponents.tsx +0 -242
- package/src/Resource/storyComponents.tsx +0 -49
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2022-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
|
-
/** @jsxImportSource @emotion/react */
|
|
10
|
-
import { ReactNode, useMemo } from "react";
|
|
11
|
-
import styled from "@emotion/styled";
|
|
12
|
-
import { spacing, colors, breakpoints, mq, stackOrder } from "@ndla/core";
|
|
13
|
-
import { Text } from "@ndla/typography";
|
|
14
|
-
import {
|
|
15
|
-
CompressedTagList,
|
|
16
|
-
ResourceImageProps,
|
|
17
|
-
resourceHeadingStyle,
|
|
18
|
-
ResourceTitleLink as StyledLink,
|
|
19
|
-
ResourceTypeList,
|
|
20
|
-
LoaderProps,
|
|
21
|
-
ContentIconWrapper,
|
|
22
|
-
} from "./resourceComponents";
|
|
23
|
-
import ContentLoader from "../ContentLoader";
|
|
24
|
-
import ContentTypeBadge from "../ContentTypeBadge";
|
|
25
|
-
import Image from "../Image";
|
|
26
|
-
import { contentTypeMapping, MISSING, resourceEmbedTypeMapping } from "../model/ContentType";
|
|
27
|
-
|
|
28
|
-
const ListResourceWrapper = styled.div`
|
|
29
|
-
flex: 1;
|
|
30
|
-
display: grid;
|
|
31
|
-
position: relative;
|
|
32
|
-
grid-template-columns: auto minmax(50px, 1fr) auto;
|
|
33
|
-
grid-template-areas:
|
|
34
|
-
"image topicAndTitle tags"
|
|
35
|
-
"image description description";
|
|
36
|
-
${mq.range({ until: breakpoints.mobileWide })} {
|
|
37
|
-
grid-template-columns: auto 1fr;
|
|
38
|
-
grid-template-areas:
|
|
39
|
-
"image topicAndTitle"
|
|
40
|
-
"description description"
|
|
41
|
-
"tags tags";
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
cursor: pointer;
|
|
45
|
-
border: 1px solid ${colors.brand.neutral7};
|
|
46
|
-
border-radius: 2px;
|
|
47
|
-
|
|
48
|
-
&:hover {
|
|
49
|
-
box-shadow: 1px 1px 6px 2px rgba(9, 55, 101, 0.08);
|
|
50
|
-
transition-duration: 0.2s;
|
|
51
|
-
[data-link] {
|
|
52
|
-
color: ${colors.brand.primary};
|
|
53
|
-
text-decoration: underline;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
`;
|
|
57
|
-
|
|
58
|
-
interface StyledImageProps {
|
|
59
|
-
imageSize: "normal" | "compact";
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const ImageWrapper = styled.div<StyledImageProps>`
|
|
63
|
-
grid-area: image;
|
|
64
|
-
width: 56px;
|
|
65
|
-
overflow: hidden;
|
|
66
|
-
border-radius: 2px;
|
|
67
|
-
display: flex;
|
|
68
|
-
margin: ${spacing.small};
|
|
69
|
-
align-items: center;
|
|
70
|
-
justify-content: center;
|
|
71
|
-
aspect-ratio: 4/3;
|
|
72
|
-
&[data-image-size="normal"] {
|
|
73
|
-
width: 136px;
|
|
74
|
-
}
|
|
75
|
-
${mq.range({ until: breakpoints.mobileWide })} {
|
|
76
|
-
width: 56px;
|
|
77
|
-
margin-bottom: 0;
|
|
78
|
-
}
|
|
79
|
-
`;
|
|
80
|
-
|
|
81
|
-
const StyledImage = styled(Image)`
|
|
82
|
-
object-fit: cover;
|
|
83
|
-
aspect-ratio: 4/3;
|
|
84
|
-
`;
|
|
85
|
-
|
|
86
|
-
const StyledResourceDescription = styled(Text)`
|
|
87
|
-
grid-area: description;
|
|
88
|
-
line-clamp: 2;
|
|
89
|
-
height: 3.1em;
|
|
90
|
-
margin: 0 ${spacing.small} ${spacing.small} 0;
|
|
91
|
-
${mq.range({ until: breakpoints.mobileWide })} {
|
|
92
|
-
margin: 0 ${spacing.small};
|
|
93
|
-
}
|
|
94
|
-
overflow: hidden;
|
|
95
|
-
text-overflow: ellipsis;
|
|
96
|
-
// Unfortunate css needed for multi-line text overflow ellipsis.
|
|
97
|
-
display: -webkit-box;
|
|
98
|
-
-webkit-line-clamp: 2;
|
|
99
|
-
line-clamp: 2;
|
|
100
|
-
-webkit-box-orient: vertical;
|
|
101
|
-
`;
|
|
102
|
-
|
|
103
|
-
const TagsandActionMenu = styled.div`
|
|
104
|
-
grid-area: tags;
|
|
105
|
-
z-index: ${stackOrder.offsetSingle};
|
|
106
|
-
box-sizing: content-box;
|
|
107
|
-
display: grid;
|
|
108
|
-
grid-template-columns: 1fr auto auto;
|
|
109
|
-
align-items: center;
|
|
110
|
-
align-self: flex-start;
|
|
111
|
-
justify-items: flex-end;
|
|
112
|
-
overflow: hidden;
|
|
113
|
-
${mq.range({ until: breakpoints.mobileWide })} {
|
|
114
|
-
min-height: ${spacing.small};
|
|
115
|
-
}
|
|
116
|
-
`;
|
|
117
|
-
|
|
118
|
-
const TopicAndTitleWrapper = styled.div`
|
|
119
|
-
grid-area: topicAndTitle;
|
|
120
|
-
display: flex;
|
|
121
|
-
margin: ${spacing.small} 0;
|
|
122
|
-
flex-direction: column;
|
|
123
|
-
overflow: hidden;
|
|
124
|
-
margin-right: ${spacing.small};
|
|
125
|
-
${mq.range({ until: breakpoints.mobileWide })} {
|
|
126
|
-
margin-bottom: 0;
|
|
127
|
-
}
|
|
128
|
-
`;
|
|
129
|
-
|
|
130
|
-
interface ListResourceImageProps {
|
|
131
|
-
resourceImage: ResourceImageProps;
|
|
132
|
-
loading?: boolean;
|
|
133
|
-
type: "normal" | "compact";
|
|
134
|
-
contentType: string;
|
|
135
|
-
background?: boolean;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const ListResourceImage = ({ resourceImage, loading, type, contentType, background }: ListResourceImageProps) => {
|
|
139
|
-
if (!loading) {
|
|
140
|
-
if (resourceImage.src === "") {
|
|
141
|
-
return (
|
|
142
|
-
<ContentIconWrapper contentType={contentType}>
|
|
143
|
-
<ContentTypeBadge type={contentType} background={background} size="x-small" />
|
|
144
|
-
</ContentIconWrapper>
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
return (
|
|
148
|
-
<StyledImage alt={resourceImage.alt} src={resourceImage.src} fallbackWidth={type === "compact" ? 56 : 136} />
|
|
149
|
-
);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return (
|
|
153
|
-
<ContentLoader height={"100%"} width={"100%"} viewBox={null} preserveAspectRatio="none">
|
|
154
|
-
<rect
|
|
155
|
-
x="0"
|
|
156
|
-
y="0"
|
|
157
|
-
rx="3"
|
|
158
|
-
ry="3"
|
|
159
|
-
width={type === "compact" ? "56" : "136"}
|
|
160
|
-
height={type === "compact" ? "40" : "96"}
|
|
161
|
-
/>
|
|
162
|
-
</ContentLoader>
|
|
163
|
-
);
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
const TypeAndTitleLoader = ({ loading, children }: LoaderProps) => {
|
|
167
|
-
if (loading) {
|
|
168
|
-
return (
|
|
169
|
-
<ContentLoader height={"40px"} width={"100%"} viewBox={null} preserveAspectRatio="none">
|
|
170
|
-
<rect x="0" y="0" rx="3" ry="3" width={"100%"} height={"16"} />
|
|
171
|
-
<rect x="0" y="18" rx="3" ry="3" width={"70"} height={"16"} />
|
|
172
|
-
<rect x="80" y="18" rx="3" ry="3" width={"70"} height={"16"} />
|
|
173
|
-
</ContentLoader>
|
|
174
|
-
);
|
|
175
|
-
}
|
|
176
|
-
return <>{children}</>;
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
interface ResourceDescriptionProps {
|
|
180
|
-
description?: string;
|
|
181
|
-
loading?: boolean;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const Description = ({ description, loading }: ResourceDescriptionProps) => {
|
|
185
|
-
if (loading) {
|
|
186
|
-
return (
|
|
187
|
-
<ContentLoader height={"20px"} width={"100%"} viewBox={null} preserveAspectRatio="none">
|
|
188
|
-
<rect x="0" y="0" width="100%" height="20" />
|
|
189
|
-
</ContentLoader>
|
|
190
|
-
);
|
|
191
|
-
}
|
|
192
|
-
return (
|
|
193
|
-
<StyledResourceDescription element="p" textStyle="meta-text-small">
|
|
194
|
-
{description}
|
|
195
|
-
</StyledResourceDescription>
|
|
196
|
-
);
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
export interface ListResourceProps {
|
|
200
|
-
id: string;
|
|
201
|
-
link: string;
|
|
202
|
-
tagLinkPrefix?: string;
|
|
203
|
-
title: string;
|
|
204
|
-
resourceImage: ResourceImageProps;
|
|
205
|
-
resourceTypes: { id: string; name: string }[];
|
|
206
|
-
tags?: string[];
|
|
207
|
-
description?: string;
|
|
208
|
-
menu?: ReactNode;
|
|
209
|
-
isLoading?: boolean;
|
|
210
|
-
targetBlank?: boolean;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
const ListResource = ({
|
|
214
|
-
id,
|
|
215
|
-
link,
|
|
216
|
-
tagLinkPrefix,
|
|
217
|
-
title,
|
|
218
|
-
tags,
|
|
219
|
-
resourceImage,
|
|
220
|
-
resourceTypes,
|
|
221
|
-
description,
|
|
222
|
-
menu,
|
|
223
|
-
isLoading = false,
|
|
224
|
-
targetBlank,
|
|
225
|
-
}: ListResourceProps) => {
|
|
226
|
-
const showDescription = description !== undefined;
|
|
227
|
-
const imageType = showDescription ? "normal" : "compact";
|
|
228
|
-
const firstContentType = resourceTypes?.[0]?.id ?? "";
|
|
229
|
-
const embedResourceType = resourceEmbedTypeMapping[firstContentType];
|
|
230
|
-
|
|
231
|
-
const contentType = useMemo(() => {
|
|
232
|
-
if (!firstContentType) {
|
|
233
|
-
return MISSING;
|
|
234
|
-
}
|
|
235
|
-
return contentTypeMapping[firstContentType] ?? embedResourceType ?? contentTypeMapping.default;
|
|
236
|
-
}, [embedResourceType, firstContentType]);
|
|
237
|
-
|
|
238
|
-
return (
|
|
239
|
-
<ListResourceWrapper id={id}>
|
|
240
|
-
<ImageWrapper imageSize={imageType} data-image-size={imageType}>
|
|
241
|
-
<ListResourceImage
|
|
242
|
-
resourceImage={resourceImage}
|
|
243
|
-
loading={isLoading}
|
|
244
|
-
type={imageType}
|
|
245
|
-
background={!!embedResourceType}
|
|
246
|
-
contentType={contentType}
|
|
247
|
-
/>
|
|
248
|
-
</ImageWrapper>
|
|
249
|
-
<TopicAndTitleWrapper>
|
|
250
|
-
<TypeAndTitleLoader loading={isLoading}>
|
|
251
|
-
<StyledLink
|
|
252
|
-
to={link}
|
|
253
|
-
data-link=""
|
|
254
|
-
target={targetBlank ? "_blank" : undefined}
|
|
255
|
-
data-resource-available={contentType !== MISSING}
|
|
256
|
-
>
|
|
257
|
-
<Text element="span" textStyle="label-small" css={resourceHeadingStyle} title={title}>
|
|
258
|
-
{title}
|
|
259
|
-
</Text>
|
|
260
|
-
</StyledLink>
|
|
261
|
-
<ResourceTypeList resourceTypes={resourceTypes} />
|
|
262
|
-
</TypeAndTitleLoader>
|
|
263
|
-
</TopicAndTitleWrapper>
|
|
264
|
-
{showDescription && <Description description={description} loading={isLoading} />}
|
|
265
|
-
<TagsandActionMenu>
|
|
266
|
-
{tags && tags.length > 0 && <CompressedTagList tagLinkPrefix={tagLinkPrefix} tags={tags} />}
|
|
267
|
-
{menu}
|
|
268
|
-
</TagsandActionMenu>
|
|
269
|
-
</ListResourceWrapper>
|
|
270
|
-
);
|
|
271
|
-
};
|
|
272
|
-
|
|
273
|
-
export default ListResource;
|
package/src/Resource/index.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2022-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 { ListResourceProps } from "./ListResource";
|
|
10
|
-
export type { ListResourceProps };
|
|
11
|
-
export { default as ListResource } from "./ListResource";
|
|
12
|
-
export { default as BlockResource } from "./BlockResource";
|
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2022-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 { CSSProperties, HTMLAttributes, ReactNode, useMemo } from "react";
|
|
10
|
-
import { useTranslation } from "react-i18next";
|
|
11
|
-
import { css } from "@emotion/react";
|
|
12
|
-
import styled from "@emotion/styled";
|
|
13
|
-
import { IconButtonV2 } from "@ndla/button";
|
|
14
|
-
import { colors, fonts, spacing, stackOrder } from "@ndla/core";
|
|
15
|
-
import { DropdownMenu, DropdownContent, DropdownTrigger, DropdownItem } from "@ndla/dropdown-menu";
|
|
16
|
-
import { HashTag } from "@ndla/icons/common";
|
|
17
|
-
import { SafeLink, SafeLinkButton } from "@ndla/safelink";
|
|
18
|
-
import { resourceEmbedTypeMapping } from "../model/ContentType";
|
|
19
|
-
import resourceTypeColor from "../utils/resourceTypeColor";
|
|
20
|
-
|
|
21
|
-
export interface ResourceImageProps {
|
|
22
|
-
alt: string;
|
|
23
|
-
src: string;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export const ResourceTitleLink = styled(SafeLink)`
|
|
27
|
-
box-shadow: none;
|
|
28
|
-
color: ${colors.brand.primary};
|
|
29
|
-
flex: 1;
|
|
30
|
-
&[data-resource-available="false"] {
|
|
31
|
-
color: ${colors.brand.grey};
|
|
32
|
-
font-style: italic;
|
|
33
|
-
}
|
|
34
|
-
:after {
|
|
35
|
-
content: "";
|
|
36
|
-
position: absolute;
|
|
37
|
-
z-index: ${stackOrder.offsetSingle};
|
|
38
|
-
top: 0;
|
|
39
|
-
right: 0;
|
|
40
|
-
bottom: 0;
|
|
41
|
-
left: 0;
|
|
42
|
-
}
|
|
43
|
-
`;
|
|
44
|
-
|
|
45
|
-
const StyledTrigger = styled(IconButtonV2)`
|
|
46
|
-
margin: 0px ${spacing.xsmall};
|
|
47
|
-
`;
|
|
48
|
-
|
|
49
|
-
export const resourceHeadingStyle = css`
|
|
50
|
-
margin: 0;
|
|
51
|
-
overflow: hidden;
|
|
52
|
-
text-overflow: ellipsis;
|
|
53
|
-
// Unfortunate css needed for multi-line text overflow ellipsis.
|
|
54
|
-
line-height: 1;
|
|
55
|
-
display: -webkit-box;
|
|
56
|
-
-webkit-line-clamp: 1;
|
|
57
|
-
line-clamp: 1;
|
|
58
|
-
-webkit-box-orient: vertical;
|
|
59
|
-
grid-area: resourceTitle;
|
|
60
|
-
`;
|
|
61
|
-
|
|
62
|
-
const StyledTagList = styled.ul`
|
|
63
|
-
list-style: none;
|
|
64
|
-
display: flex;
|
|
65
|
-
margin-left: ${spacing.small};
|
|
66
|
-
padding: 2px;
|
|
67
|
-
gap: ${spacing.xsmall};
|
|
68
|
-
overflow: hidden;
|
|
69
|
-
:last-child {
|
|
70
|
-
margin-right: ${spacing.small};
|
|
71
|
-
}
|
|
72
|
-
`;
|
|
73
|
-
|
|
74
|
-
const StyledTagListElement = styled.li`
|
|
75
|
-
padding: 0;
|
|
76
|
-
${fonts.sizes(14)};
|
|
77
|
-
`;
|
|
78
|
-
|
|
79
|
-
const StyledSafeLink = styled(SafeLink)`
|
|
80
|
-
display: flex;
|
|
81
|
-
justify-content: flex-end;
|
|
82
|
-
align-items: center;
|
|
83
|
-
box-shadow: none;
|
|
84
|
-
color: ${colors.brand.grey};
|
|
85
|
-
min-height: 44px;
|
|
86
|
-
min-width: 44px;
|
|
87
|
-
white-space: nowrap;
|
|
88
|
-
&:hover {
|
|
89
|
-
color: ${colors.brand.primary};
|
|
90
|
-
}
|
|
91
|
-
`;
|
|
92
|
-
|
|
93
|
-
const StyledResourceTypeList = styled.ul`
|
|
94
|
-
list-style: none;
|
|
95
|
-
display: flex;
|
|
96
|
-
margin: 0;
|
|
97
|
-
padding: 0;
|
|
98
|
-
overflow: hidden;
|
|
99
|
-
`;
|
|
100
|
-
|
|
101
|
-
const StyledTopicDivider = styled.span`
|
|
102
|
-
margin: 0;
|
|
103
|
-
padding: 0 ${spacing.xxsmall};
|
|
104
|
-
`;
|
|
105
|
-
|
|
106
|
-
const StyledResourceListElement = styled.li`
|
|
107
|
-
white-space: nowrap;
|
|
108
|
-
${fonts.sizes(12)};
|
|
109
|
-
margin: 0;
|
|
110
|
-
line-height: 1.5;
|
|
111
|
-
padding: 0;
|
|
112
|
-
display: flex;
|
|
113
|
-
align-items: center;
|
|
114
|
-
`;
|
|
115
|
-
|
|
116
|
-
const TagCounterWrapper = styled.span`
|
|
117
|
-
display: flex;
|
|
118
|
-
font-weight: ${fonts.weight.semibold};
|
|
119
|
-
${fonts.sizes("14px", "14px")};
|
|
120
|
-
`;
|
|
121
|
-
|
|
122
|
-
interface ContentIconProps extends HTMLAttributes<HTMLSpanElement> {
|
|
123
|
-
contentType: string;
|
|
124
|
-
children?: ReactNode;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const StyledContentIconWrapper = styled.span`
|
|
128
|
-
width: 100%;
|
|
129
|
-
aspect-ratio: 4/3;
|
|
130
|
-
display: flex;
|
|
131
|
-
align-items: center;
|
|
132
|
-
justify-content: center;
|
|
133
|
-
background-color: var(--content-background-color);
|
|
134
|
-
`;
|
|
135
|
-
|
|
136
|
-
export const ContentIconWrapper = ({ contentType, children, ...props }: ContentIconProps) => {
|
|
137
|
-
const contentIconWrapperVars = useMemo(
|
|
138
|
-
() =>
|
|
139
|
-
({
|
|
140
|
-
"--content-background-color": resourceTypeColor(contentType),
|
|
141
|
-
}) as unknown as CSSProperties,
|
|
142
|
-
[contentType],
|
|
143
|
-
);
|
|
144
|
-
return (
|
|
145
|
-
<StyledContentIconWrapper {...props} style={contentIconWrapperVars}>
|
|
146
|
-
{children}
|
|
147
|
-
</StyledContentIconWrapper>
|
|
148
|
-
);
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
interface TagListProps {
|
|
152
|
-
tags?: string[];
|
|
153
|
-
tagLinkPrefix?: string;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
export interface LoaderProps {
|
|
157
|
-
loading?: boolean;
|
|
158
|
-
children?: ReactNode;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export const TagList = ({ tags, tagLinkPrefix }: TagListProps) => {
|
|
162
|
-
const { t } = useTranslation();
|
|
163
|
-
if (!tags) return null;
|
|
164
|
-
return (
|
|
165
|
-
<StyledTagList aria-label={t("myNdla.tagList")}>
|
|
166
|
-
{tags.map((tag, i) => (
|
|
167
|
-
<StyledTagListElement key={`tag-${i}`}>
|
|
168
|
-
<StyledSafeLink to={`${tagLinkPrefix ? tagLinkPrefix : ""}/${encodeURIComponent(tag)}`}>
|
|
169
|
-
<HashTag />
|
|
170
|
-
{tag}
|
|
171
|
-
</StyledSafeLink>
|
|
172
|
-
</StyledTagListElement>
|
|
173
|
-
))}
|
|
174
|
-
</StyledTagList>
|
|
175
|
-
);
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
interface CompressedTagListProps {
|
|
179
|
-
tags: string[];
|
|
180
|
-
tagLinkPrefix?: string;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
export const CompressedTagList = ({ tags, tagLinkPrefix }: CompressedTagListProps) => {
|
|
184
|
-
const { t } = useTranslation();
|
|
185
|
-
const visibleTags = useMemo(() => tags.slice(0, 3), [tags]);
|
|
186
|
-
const remainingTags = useMemo(() => tags.slice(3, tags.length), [tags]);
|
|
187
|
-
|
|
188
|
-
return (
|
|
189
|
-
<>
|
|
190
|
-
<TagList tagLinkPrefix={tagLinkPrefix} tags={visibleTags} />
|
|
191
|
-
{remainingTags.length > 0 && (
|
|
192
|
-
<DropdownMenu>
|
|
193
|
-
<DropdownTrigger>
|
|
194
|
-
<StyledTrigger
|
|
195
|
-
size="xsmall"
|
|
196
|
-
variant="ghost"
|
|
197
|
-
colorTheme="light"
|
|
198
|
-
aria-label={t("myNdla.moreTags", { count: remainingTags.length })}
|
|
199
|
-
>
|
|
200
|
-
{<TagCounterWrapper>{`+${remainingTags.length}`}</TagCounterWrapper>}
|
|
201
|
-
</StyledTrigger>
|
|
202
|
-
</DropdownTrigger>
|
|
203
|
-
<DropdownContent showArrow>
|
|
204
|
-
{remainingTags.map((tag, i) => (
|
|
205
|
-
<DropdownItem key={`tag-${i}`}>
|
|
206
|
-
<SafeLinkButton
|
|
207
|
-
to={`${tagLinkPrefix ?? ""}/${encodeURIComponent(tag)}`}
|
|
208
|
-
variant="ghost"
|
|
209
|
-
colorTheme="light"
|
|
210
|
-
>
|
|
211
|
-
<HashTag />
|
|
212
|
-
{tag}
|
|
213
|
-
</SafeLinkButton>
|
|
214
|
-
</DropdownItem>
|
|
215
|
-
))}
|
|
216
|
-
</DropdownContent>
|
|
217
|
-
</DropdownMenu>
|
|
218
|
-
)}
|
|
219
|
-
</>
|
|
220
|
-
);
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
interface ResourceTypeListProps {
|
|
224
|
-
resourceTypes?: { id: string; name: string }[];
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
export const ResourceTypeList = ({ resourceTypes }: ResourceTypeListProps) => {
|
|
228
|
-
const { t } = useTranslation();
|
|
229
|
-
if (!resourceTypes) return null;
|
|
230
|
-
return (
|
|
231
|
-
<StyledResourceTypeList aria-label={t("navigation.topics")}>
|
|
232
|
-
{resourceTypes.map((resource, i) => (
|
|
233
|
-
<StyledResourceListElement key={resource.id}>
|
|
234
|
-
{resourceEmbedTypeMapping[resource.id]
|
|
235
|
-
? t(`embed.type.${resourceEmbedTypeMapping[resource.id]}`)
|
|
236
|
-
: resource.name}
|
|
237
|
-
{i !== resourceTypes.length - 1 && <StyledTopicDivider aria-hidden="true">•</StyledTopicDivider>}
|
|
238
|
-
</StyledResourceListElement>
|
|
239
|
-
))}
|
|
240
|
-
</StyledResourceTypeList>
|
|
241
|
-
);
|
|
242
|
-
};
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2022-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 { IconButtonV2, ButtonV2 } from "@ndla/button";
|
|
10
|
-
import { DropdownMenu, DropdownTrigger, DropdownContent, DropdownItem } from "@ndla/dropdown-menu";
|
|
11
|
-
import { Pencil } from "@ndla/icons/action";
|
|
12
|
-
import { HorizontalMenu } from "@ndla/icons/contentType";
|
|
13
|
-
import { DeleteForever } from "@ndla/icons/editor";
|
|
14
|
-
|
|
15
|
-
export const resourceTypesArr = [
|
|
16
|
-
{ id: "urn:resourcetype:learningPath", name: "Læringssti" },
|
|
17
|
-
{ id: "urn:resourcetype:subjectMaterial", name: "Fagstoff" },
|
|
18
|
-
{
|
|
19
|
-
id: "urn:resourcetype:tasksAndActivities",
|
|
20
|
-
name: "Oppgaver og aktiviteter",
|
|
21
|
-
},
|
|
22
|
-
{ id: "urn:resourcetype:reviewResource", name: "Vurderingsressurs" },
|
|
23
|
-
{ id: "urn:resourcetype:externalResource", name: "Ekstern læringsressurs" },
|
|
24
|
-
{ id: "urn:resourcetype:SourceMaterial", name: "Kildemateriale" },
|
|
25
|
-
];
|
|
26
|
-
|
|
27
|
-
export const StoryResourceMenu = () => (
|
|
28
|
-
<DropdownMenu>
|
|
29
|
-
<DropdownTrigger>
|
|
30
|
-
<IconButtonV2 aria-label="Show more" title="Show more" variant="ghost" colorTheme="light">
|
|
31
|
-
<HorizontalMenu />
|
|
32
|
-
</IconButtonV2>
|
|
33
|
-
</DropdownTrigger>
|
|
34
|
-
<DropdownContent>
|
|
35
|
-
<DropdownItem>
|
|
36
|
-
<ButtonV2 variant="ghost" colorTheme="light" shape="sharp" size="small" fontWeight="normal">
|
|
37
|
-
<Pencil />
|
|
38
|
-
Rediger
|
|
39
|
-
</ButtonV2>
|
|
40
|
-
</DropdownItem>
|
|
41
|
-
<DropdownItem>
|
|
42
|
-
<ButtonV2 variant="ghost" colorTheme="danger" shape="sharp" size="small" fontWeight="normal">
|
|
43
|
-
<DeleteForever />
|
|
44
|
-
Slett
|
|
45
|
-
</ButtonV2>
|
|
46
|
-
</DropdownItem>
|
|
47
|
-
</DropdownContent>
|
|
48
|
-
</DropdownMenu>
|
|
49
|
-
);
|