@gravity-ui/blog-constructor 5.8.0-alpha.0 → 5.8.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/build/cjs/blocks/Author/schema.d.ts +3 -0
- package/build/cjs/blocks/Banner/schema.d.ts +6 -0
- package/build/cjs/blocks/CTA/schema.d.ts +6 -0
- package/build/cjs/blocks/ColoredText/schema.d.ts +6 -0
- package/build/cjs/blocks/Feed/schema.d.ts +6 -0
- package/build/cjs/blocks/Header/schema.d.ts +3 -0
- package/build/cjs/blocks/Layout/schema.d.ts +3 -0
- package/build/cjs/blocks/Media/schema.d.ts +3 -0
- package/build/cjs/blocks/Meta/schema.d.ts +3 -0
- package/build/cjs/blocks/Suggest/schema.d.ts +3 -0
- package/build/cjs/blocks/YFM/schema.d.ts +3 -0
- package/build/cjs/components/PostCard/PostCard.js +21 -5
- package/build/cjs/components/PostInfo/SuggestPostInfo.d.ts +5 -1
- package/build/cjs/components/PostInfo/SuggestPostInfo.js +5 -3
- package/build/cjs/components/PostInfo/components/Date.d.ts +2 -1
- package/build/cjs/components/PostInfo/components/Date.js +2 -2
- package/build/cjs/components/PostInfo/components/ReadingTime.d.ts +2 -1
- package/build/cjs/components/PostInfo/components/ReadingTime.js +1 -1
- package/build/cjs/hooks/useAriaAttributes.d.ts +17 -0
- package/build/cjs/hooks/useAriaAttributes.js +19 -0
- package/build/cjs/schema/index.d.ts +45 -0
- package/build/esm/blocks/Author/schema.d.ts +3 -0
- package/build/esm/blocks/Banner/schema.d.ts +6 -0
- package/build/esm/blocks/CTA/schema.d.ts +6 -0
- package/build/esm/blocks/ColoredText/schema.d.ts +6 -0
- package/build/esm/blocks/Feed/schema.d.ts +6 -0
- package/build/esm/blocks/Header/schema.d.ts +3 -0
- package/build/esm/blocks/Layout/schema.d.ts +3 -0
- package/build/esm/blocks/Media/schema.d.ts +3 -0
- package/build/esm/blocks/Meta/schema.d.ts +3 -0
- package/build/esm/blocks/Suggest/schema.d.ts +3 -0
- package/build/esm/blocks/YFM/schema.d.ts +3 -0
- package/build/esm/components/PostCard/PostCard.js +21 -5
- package/build/esm/components/PostInfo/SuggestPostInfo.d.ts +5 -1
- package/build/esm/components/PostInfo/SuggestPostInfo.js +5 -3
- package/build/esm/components/PostInfo/components/Date.d.ts +2 -1
- package/build/esm/components/PostInfo/components/Date.js +2 -2
- package/build/esm/components/PostInfo/components/ReadingTime.d.ts +2 -1
- package/build/esm/components/PostInfo/components/ReadingTime.js +1 -1
- package/build/esm/hooks/useAriaAttributes.d.ts +17 -0
- package/build/esm/hooks/useAriaAttributes.js +15 -0
- package/build/esm/schema/index.d.ts +45 -0
- package/package.json +3 -4
@@ -36,6 +36,9 @@ export declare const Banner: {
|
|
36
36
|
url: {
|
37
37
|
type: string;
|
38
38
|
};
|
39
|
+
urlTitle: {
|
40
|
+
type: string;
|
41
|
+
};
|
39
42
|
resetMargin: {
|
40
43
|
type: string;
|
41
44
|
};
|
@@ -123,6 +126,9 @@ export declare const Banner: {
|
|
123
126
|
url: {
|
124
127
|
type: string;
|
125
128
|
};
|
129
|
+
urlTitle: {
|
130
|
+
type: string;
|
131
|
+
};
|
126
132
|
};
|
127
133
|
};
|
128
134
|
visible: {
|
@@ -33,6 +33,9 @@ export declare const CTA: {
|
|
33
33
|
url: {
|
34
34
|
type: string;
|
35
35
|
};
|
36
|
+
urlTitle: {
|
37
|
+
type: string;
|
38
|
+
};
|
36
39
|
resetMargin: {
|
37
40
|
type: string;
|
38
41
|
};
|
@@ -123,6 +126,9 @@ export declare const CTA: {
|
|
123
126
|
url: {
|
124
127
|
type: string;
|
125
128
|
};
|
129
|
+
urlTitle: {
|
130
|
+
type: string;
|
131
|
+
};
|
126
132
|
};
|
127
133
|
};
|
128
134
|
visible: {
|
@@ -53,6 +53,9 @@ export declare const ColoredText: {
|
|
53
53
|
url: {
|
54
54
|
type: string;
|
55
55
|
};
|
56
|
+
urlTitle: {
|
57
|
+
type: string;
|
58
|
+
};
|
56
59
|
resetMargin: {
|
57
60
|
type: string;
|
58
61
|
};
|
@@ -140,6 +143,9 @@ export declare const ColoredText: {
|
|
140
143
|
url: {
|
141
144
|
type: string;
|
142
145
|
};
|
146
|
+
urlTitle: {
|
147
|
+
type: string;
|
148
|
+
};
|
143
149
|
};
|
144
150
|
};
|
145
151
|
visible: {
|
@@ -19,6 +19,9 @@ export declare const Feed: {
|
|
19
19
|
url: {
|
20
20
|
type: string;
|
21
21
|
};
|
22
|
+
urlTitle: {
|
23
|
+
type: string;
|
24
|
+
};
|
22
25
|
resetMargin: {
|
23
26
|
type: string;
|
24
27
|
};
|
@@ -47,6 +50,9 @@ export declare const Feed: {
|
|
47
50
|
url: {
|
48
51
|
type: string;
|
49
52
|
};
|
53
|
+
urlTitle: {
|
54
|
+
type: string;
|
55
|
+
};
|
50
56
|
};
|
51
57
|
};
|
52
58
|
visible: {
|
@@ -4,10 +4,12 @@ exports.PostCard = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
5
5
|
const react_1 = tslib_1.__importStar(require("react"));
|
6
6
|
const page_constructor_1 = require("@gravity-ui/page-constructor");
|
7
|
+
const uikit_1 = require("@gravity-ui/uikit");
|
7
8
|
const LikesContext_1 = require("../../contexts/LikesContext");
|
8
9
|
const common_1 = require("../../models/common");
|
9
10
|
const cn_1 = require("../../utils/cn");
|
10
11
|
const SuggestPostInfo_1 = require("../PostInfo/SuggestPostInfo");
|
12
|
+
const useAriaAttributes_1 = require("../../hooks/useAriaAttributes");
|
11
13
|
const b = (0, cn_1.block)('post-card');
|
12
14
|
const PostCard = ({ post, metrikaGoals, fullWidth = false, size = common_1.PostCardSize.SMALL, showTag = false, titleHeadingLevel = common_1.PostCardTitleHeadingLevel.H3, }) => {
|
13
15
|
var _a;
|
@@ -21,19 +23,33 @@ const PostCard = ({ post, metrikaGoals, fullWidth = false, size = common_1.PostC
|
|
21
23
|
toggleLike,
|
22
24
|
}
|
23
25
|
: undefined, [hasUserLike, likes, toggleLike, hasLikes]);
|
24
|
-
|
26
|
+
const titleId = (0, uikit_1.useUniqId)();
|
27
|
+
const descriptionId = (0, uikit_1.useUniqId)();
|
28
|
+
const dateId = (0, uikit_1.useUniqId)();
|
29
|
+
const tagId = (0, uikit_1.useUniqId)();
|
30
|
+
const readingTimeId = (0, uikit_1.useUniqId)();
|
31
|
+
const isTagVisible = showTag && ((_a = tags === null || tags === void 0 ? void 0 : tags[0]) === null || _a === void 0 ? void 0 : _a.name);
|
32
|
+
const ariaAttributes = (0, useAriaAttributes_1.useAriaAttributes)({
|
33
|
+
labelIds: [isTagVisible && tagId, title && titleId],
|
34
|
+
descriptionIds: [
|
35
|
+
description && descriptionId,
|
36
|
+
date && dateId,
|
37
|
+
readingTime && readingTimeId,
|
38
|
+
],
|
39
|
+
});
|
40
|
+
return (react_1.default.createElement(page_constructor_1.CardBase, { url: url, metrikaGoals: metrikaGoals, className: b('card', { fullWidth }), extraProps: ariaAttributes },
|
25
41
|
react_1.default.createElement(page_constructor_1.CardBase.Header, { image: image, className: b('header', { fullWidth }) },
|
26
42
|
react_1.default.createElement("div", { className: b('image-container'), "data-qa": "blog-suggest-header" })),
|
27
43
|
react_1.default.createElement(page_constructor_1.CardBase.Content, null,
|
28
|
-
|
44
|
+
isTagVisible && (react_1.default.createElement("div", { id: tagId, className: b('tag', { size }) }, tags[0].name)),
|
29
45
|
title &&
|
30
46
|
react_1.default.createElement(titleHeadingLevel, { className: b('title', { size }) }, react_1.default.createElement("span", null,
|
31
|
-
react_1.default.createElement(page_constructor_1.HTML,
|
47
|
+
react_1.default.createElement(page_constructor_1.HTML, { id: titleId }, title))),
|
32
48
|
description && (react_1.default.createElement(page_constructor_1.YFMWrapper, { className: b('description'), content: description, modifiers: {
|
33
49
|
blog: size === 'm',
|
34
50
|
blogCard: true,
|
35
|
-
} }))),
|
51
|
+
}, id: descriptionId }))),
|
36
52
|
react_1.default.createElement(page_constructor_1.CardBase.Footer, null,
|
37
|
-
react_1.default.createElement(SuggestPostInfo_1.SuggestPostInfo, { postId: blogPostId || id, date: date, readingTime: readingTime, hasUserLike: hasUserLike, likes: likesProps, size: size, qa: "blog-suggest-block" }))));
|
53
|
+
react_1.default.createElement(SuggestPostInfo_1.SuggestPostInfo, { postId: blogPostId || id, date: date, readingTime: readingTime, hasUserLike: hasUserLike, likes: likesProps, size: size, qa: "blog-suggest-block", dateId: dateId, readingTimeId: readingTimeId }))));
|
38
54
|
};
|
39
55
|
exports.PostCard = PostCard;
|
@@ -8,6 +8,8 @@ export interface SuggestPostInfoProps extends Pick<PostData, 'date' | 'readingTi
|
|
8
8
|
hasUserLike?: boolean;
|
9
9
|
toggleLike?: ToggleLikeCallbackType;
|
10
10
|
};
|
11
|
+
dateId?: string;
|
12
|
+
readingTimeId?: string;
|
11
13
|
}
|
12
14
|
/**
|
13
15
|
* Suggest blog card info component
|
@@ -20,7 +22,9 @@ export interface SuggestPostInfoProps extends Pick<PostData, 'date' | 'readingTi
|
|
20
22
|
* @param qa - test-attr
|
21
23
|
* @param size - text size
|
22
24
|
* @param isModernIcon - flag what we need render 'bookmark' icon
|
25
|
+
* @param dateId - id value for element with post date. Useful when providing accessible description
|
26
|
+
* @param readingTimeId - id value for element with reading time. Useful when providing accessible description
|
23
27
|
*
|
24
28
|
* @returns jsx
|
25
29
|
*/
|
26
|
-
export declare const SuggestPostInfo: ({ postId, date, readingTime, likes, size, qa, }: SuggestPostInfoProps) => React.JSX.Element;
|
30
|
+
export declare const SuggestPostInfo: ({ postId, date, readingTime, likes, size, qa, dateId, readingTimeId, }: SuggestPostInfoProps) => React.JSX.Element;
|
@@ -21,10 +21,12 @@ const b = (0, cn_1.block)('post-info');
|
|
21
21
|
* @param qa - test-attr
|
22
22
|
* @param size - text size
|
23
23
|
* @param isModernIcon - flag what we need render 'bookmark' icon
|
24
|
+
* @param dateId - id value for element with post date. Useful when providing accessible description
|
25
|
+
* @param readingTimeId - id value for element with reading time. Useful when providing accessible description
|
24
26
|
*
|
25
27
|
* @returns jsx
|
26
28
|
*/
|
27
|
-
const SuggestPostInfo = ({ postId, date, readingTime, likes, size = common_1.PostCardSize.SMALL, qa, }) => {
|
29
|
+
const SuggestPostInfo = ({ postId, date, readingTime, likes, size = common_1.PostCardSize.SMALL, qa, dateId, readingTimeId, }) => {
|
28
30
|
const { hasUserLike, likesCount, handleLike } = (0, useLikes_1.useLikes)({
|
29
31
|
hasLike: likes === null || likes === void 0 ? void 0 : likes.hasUserLike,
|
30
32
|
count: likes === null || likes === void 0 ? void 0 : likes.likesCount,
|
@@ -33,8 +35,8 @@ const SuggestPostInfo = ({ postId, date, readingTime, likes, size = common_1.Pos
|
|
33
35
|
});
|
34
36
|
return (react_1.default.createElement("div", { className: b('container') },
|
35
37
|
react_1.default.createElement("div", { className: b('suggest-container') },
|
36
|
-
date && react_1.default.createElement(Date_1.Date, { date: date, size: size }),
|
37
|
-
readingTime && react_1.default.createElement(ReadingTime_1.ReadingTime, { readingTime: readingTime, size: size })),
|
38
|
+
date && react_1.default.createElement(Date_1.Date, { date: date, size: size, id: dateId }),
|
39
|
+
readingTime && (react_1.default.createElement(ReadingTime_1.ReadingTime, { readingTime: readingTime, size: size, id: readingTimeId }))),
|
38
40
|
likes && postId && (react_1.default.createElement(Save_1.Save, { postId: postId, title: likesCount, hasUserLike: hasUserLike, handleUserLike: handleLike, size: size, qa: qa }))));
|
39
41
|
};
|
40
42
|
exports.SuggestPostInfo = SuggestPostInfo;
|
@@ -3,6 +3,7 @@ import { PostCardSize } from '../../../models/common';
|
|
3
3
|
type DateProps = {
|
4
4
|
date: string | number;
|
5
5
|
size?: PostCardSize;
|
6
|
+
id?: string;
|
6
7
|
};
|
7
|
-
export declare const Date: ({ date, size }: DateProps) => React.JSX.Element;
|
8
|
+
export declare const Date: ({ date, size, id }: DateProps) => React.JSX.Element;
|
8
9
|
export {};
|
@@ -8,8 +8,8 @@ const common_1 = require("../../../models/common");
|
|
8
8
|
const cn_1 = require("../../../utils/cn");
|
9
9
|
const date_1 = require("../../../utils/date");
|
10
10
|
const b = (0, cn_1.block)('post-info');
|
11
|
-
const Date = ({ date, size = common_1.PostCardSize.SMALL }) => {
|
11
|
+
const Date = ({ date, size = common_1.PostCardSize.SMALL, id }) => {
|
12
12
|
const { locale } = (0, react_1.useContext)(LocaleContext_1.LocaleContext);
|
13
|
-
return react_1.default.createElement("div", { className: b('item', { size }) }, (0, date_1.format)(date, 'longDate', locale === null || locale === void 0 ? void 0 : locale.code));
|
13
|
+
return (react_1.default.createElement("div", { className: b('item', { size }), id: id }, (0, date_1.format)(date, 'longDate', locale === null || locale === void 0 ? void 0 : locale.code)));
|
14
14
|
};
|
15
15
|
exports.Date = Date;
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
2
2
|
type ReadingTimeProps = {
|
3
3
|
readingTime: number;
|
4
4
|
size?: 's' | 'm';
|
5
|
+
id?: string;
|
5
6
|
};
|
6
|
-
export declare const ReadingTime: ({ readingTime, size }: ReadingTimeProps) => React.JSX.Element;
|
7
|
+
export declare const ReadingTime: ({ readingTime, size, id }: ReadingTimeProps) => React.JSX.Element;
|
7
8
|
export {};
|
@@ -9,7 +9,7 @@ const Time_1 = require("../../../icons/Time");
|
|
9
9
|
const cn_1 = require("../../../utils/cn");
|
10
10
|
const b = (0, cn_1.block)('post-info');
|
11
11
|
const ICON_SIZE = 16;
|
12
|
-
const ReadingTime = ({ readingTime, size = 's' }) => (react_1.default.createElement("div", { className: b('item', { size }) },
|
12
|
+
const ReadingTime = ({ readingTime, size = 's', id }) => (react_1.default.createElement("div", { className: b('item', { size }), id: id },
|
13
13
|
react_1.default.createElement("span", { className: b('icon') },
|
14
14
|
react_1.default.createElement(uikit_1.Icon, { data: Time_1.Time, size: ICON_SIZE, className: b('icon-color') })),
|
15
15
|
(0, i18n_1.i18)(i18n_1.Keyset.ContextReadingTime, { count: readingTime })));
|
@@ -0,0 +1,17 @@
|
|
1
|
+
type Labels = string | number | boolean | undefined;
|
2
|
+
type Description = string | number | boolean | undefined;
|
3
|
+
interface UseAriaAttributesProps {
|
4
|
+
labelIds?: Labels[];
|
5
|
+
descriptionIds: Description[];
|
6
|
+
}
|
7
|
+
/**
|
8
|
+
* Returns aria-attributes
|
9
|
+
* @param labelIds - labels ids. Falsy values will be ignored
|
10
|
+
* @param descriptionIds - descriptions ids. Falsy values will be ignored
|
11
|
+
* @returns aria attributes for the element to be labelled
|
12
|
+
*/
|
13
|
+
export declare const useAriaAttributes: ({ labelIds, descriptionIds }: UseAriaAttributesProps) => {
|
14
|
+
'aria-labelledby': string;
|
15
|
+
'aria-describedby': string;
|
16
|
+
};
|
17
|
+
export {};
|
@@ -0,0 +1,19 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.useAriaAttributes = void 0;
|
4
|
+
const react_1 = require("react");
|
5
|
+
/**
|
6
|
+
* Returns aria-attributes
|
7
|
+
* @param labelIds - labels ids. Falsy values will be ignored
|
8
|
+
* @param descriptionIds - descriptions ids. Falsy values will be ignored
|
9
|
+
* @returns aria attributes for the element to be labelled
|
10
|
+
*/
|
11
|
+
const useAriaAttributes = ({ labelIds = [], descriptionIds = [] }) => {
|
12
|
+
const labelledBy = (0, react_1.useMemo)(() => labelIds.filter(Boolean).join(' '), [labelIds]);
|
13
|
+
const describedBy = (0, react_1.useMemo)(() => descriptionIds.filter(Boolean).join(' '), [descriptionIds]);
|
14
|
+
return {
|
15
|
+
'aria-labelledby': labelledBy,
|
16
|
+
'aria-describedby': describedBy,
|
17
|
+
};
|
18
|
+
};
|
19
|
+
exports.useAriaAttributes = useAriaAttributes;
|
@@ -519,6 +519,9 @@ export declare const schemasForCustom: {
|
|
519
519
|
url: {
|
520
520
|
type: string;
|
521
521
|
};
|
522
|
+
urlTitle: {
|
523
|
+
type: string;
|
524
|
+
};
|
522
525
|
};
|
523
526
|
};
|
524
527
|
visible: {
|
@@ -579,6 +582,9 @@ export declare const schemasForCustom: {
|
|
579
582
|
url: {
|
580
583
|
type: string;
|
581
584
|
};
|
585
|
+
urlTitle: {
|
586
|
+
type: string;
|
587
|
+
};
|
582
588
|
};
|
583
589
|
};
|
584
590
|
visible: {
|
@@ -636,6 +642,9 @@ export declare const schemasForCustom: {
|
|
636
642
|
url: {
|
637
643
|
type: string;
|
638
644
|
};
|
645
|
+
urlTitle: {
|
646
|
+
type: string;
|
647
|
+
};
|
639
648
|
resetMargin: {
|
640
649
|
type: string;
|
641
650
|
};
|
@@ -723,6 +732,9 @@ export declare const schemasForCustom: {
|
|
723
732
|
url: {
|
724
733
|
type: string;
|
725
734
|
};
|
735
|
+
urlTitle: {
|
736
|
+
type: string;
|
737
|
+
};
|
726
738
|
};
|
727
739
|
};
|
728
740
|
visible: {
|
@@ -797,6 +809,9 @@ export declare const schemasForCustom: {
|
|
797
809
|
url: {
|
798
810
|
type: string;
|
799
811
|
};
|
812
|
+
urlTitle: {
|
813
|
+
type: string;
|
814
|
+
};
|
800
815
|
resetMargin: {
|
801
816
|
type: string;
|
802
817
|
};
|
@@ -884,6 +899,9 @@ export declare const schemasForCustom: {
|
|
884
899
|
url: {
|
885
900
|
type: string;
|
886
901
|
};
|
902
|
+
urlTitle: {
|
903
|
+
type: string;
|
904
|
+
};
|
887
905
|
};
|
888
906
|
};
|
889
907
|
visible: {
|
@@ -938,6 +956,9 @@ export declare const schemasForCustom: {
|
|
938
956
|
url: {
|
939
957
|
type: string;
|
940
958
|
};
|
959
|
+
urlTitle: {
|
960
|
+
type: string;
|
961
|
+
};
|
941
962
|
resetMargin: {
|
942
963
|
type: string;
|
943
964
|
};
|
@@ -1028,6 +1049,9 @@ export declare const schemasForCustom: {
|
|
1028
1049
|
url: {
|
1029
1050
|
type: string;
|
1030
1051
|
};
|
1052
|
+
urlTitle: {
|
1053
|
+
type: string;
|
1054
|
+
};
|
1031
1055
|
};
|
1032
1056
|
};
|
1033
1057
|
visible: {
|
@@ -1068,6 +1092,9 @@ export declare const schemasForCustom: {
|
|
1068
1092
|
url: {
|
1069
1093
|
type: string;
|
1070
1094
|
};
|
1095
|
+
urlTitle: {
|
1096
|
+
type: string;
|
1097
|
+
};
|
1071
1098
|
resetMargin: {
|
1072
1099
|
type: string;
|
1073
1100
|
};
|
@@ -1096,6 +1123,9 @@ export declare const schemasForCustom: {
|
|
1096
1123
|
url: {
|
1097
1124
|
type: string;
|
1098
1125
|
};
|
1126
|
+
urlTitle: {
|
1127
|
+
type: string;
|
1128
|
+
};
|
1099
1129
|
};
|
1100
1130
|
};
|
1101
1131
|
visible: {
|
@@ -1161,6 +1191,9 @@ export declare const schemasForCustom: {
|
|
1161
1191
|
url: {
|
1162
1192
|
type: string;
|
1163
1193
|
};
|
1194
|
+
urlTitle: {
|
1195
|
+
type: string;
|
1196
|
+
};
|
1164
1197
|
};
|
1165
1198
|
};
|
1166
1199
|
visible: {
|
@@ -1461,6 +1494,9 @@ export declare const schemasForCustom: {
|
|
1461
1494
|
url: {
|
1462
1495
|
type: string;
|
1463
1496
|
};
|
1497
|
+
urlTitle: {
|
1498
|
+
type: string;
|
1499
|
+
};
|
1464
1500
|
};
|
1465
1501
|
};
|
1466
1502
|
visible: {
|
@@ -1515,6 +1551,9 @@ export declare const schemasForCustom: {
|
|
1515
1551
|
url: {
|
1516
1552
|
type: string;
|
1517
1553
|
};
|
1554
|
+
urlTitle: {
|
1555
|
+
type: string;
|
1556
|
+
};
|
1518
1557
|
};
|
1519
1558
|
};
|
1520
1559
|
visible: {
|
@@ -1569,6 +1608,9 @@ export declare const schemasForCustom: {
|
|
1569
1608
|
url: {
|
1570
1609
|
type: string;
|
1571
1610
|
};
|
1611
|
+
urlTitle: {
|
1612
|
+
type: string;
|
1613
|
+
};
|
1572
1614
|
};
|
1573
1615
|
};
|
1574
1616
|
visible: {
|
@@ -1628,6 +1670,9 @@ export declare const schemasForCustom: {
|
|
1628
1670
|
url: {
|
1629
1671
|
type: string;
|
1630
1672
|
};
|
1673
|
+
urlTitle: {
|
1674
|
+
type: string;
|
1675
|
+
};
|
1631
1676
|
};
|
1632
1677
|
};
|
1633
1678
|
visible: {
|
@@ -36,6 +36,9 @@ export declare const Banner: {
|
|
36
36
|
url: {
|
37
37
|
type: string;
|
38
38
|
};
|
39
|
+
urlTitle: {
|
40
|
+
type: string;
|
41
|
+
};
|
39
42
|
resetMargin: {
|
40
43
|
type: string;
|
41
44
|
};
|
@@ -123,6 +126,9 @@ export declare const Banner: {
|
|
123
126
|
url: {
|
124
127
|
type: string;
|
125
128
|
};
|
129
|
+
urlTitle: {
|
130
|
+
type: string;
|
131
|
+
};
|
126
132
|
};
|
127
133
|
};
|
128
134
|
visible: {
|
@@ -33,6 +33,9 @@ export declare const CTA: {
|
|
33
33
|
url: {
|
34
34
|
type: string;
|
35
35
|
};
|
36
|
+
urlTitle: {
|
37
|
+
type: string;
|
38
|
+
};
|
36
39
|
resetMargin: {
|
37
40
|
type: string;
|
38
41
|
};
|
@@ -123,6 +126,9 @@ export declare const CTA: {
|
|
123
126
|
url: {
|
124
127
|
type: string;
|
125
128
|
};
|
129
|
+
urlTitle: {
|
130
|
+
type: string;
|
131
|
+
};
|
126
132
|
};
|
127
133
|
};
|
128
134
|
visible: {
|
@@ -53,6 +53,9 @@ export declare const ColoredText: {
|
|
53
53
|
url: {
|
54
54
|
type: string;
|
55
55
|
};
|
56
|
+
urlTitle: {
|
57
|
+
type: string;
|
58
|
+
};
|
56
59
|
resetMargin: {
|
57
60
|
type: string;
|
58
61
|
};
|
@@ -140,6 +143,9 @@ export declare const ColoredText: {
|
|
140
143
|
url: {
|
141
144
|
type: string;
|
142
145
|
};
|
146
|
+
urlTitle: {
|
147
|
+
type: string;
|
148
|
+
};
|
143
149
|
};
|
144
150
|
};
|
145
151
|
visible: {
|
@@ -19,6 +19,9 @@ export declare const Feed: {
|
|
19
19
|
url: {
|
20
20
|
type: string;
|
21
21
|
};
|
22
|
+
urlTitle: {
|
23
|
+
type: string;
|
24
|
+
};
|
22
25
|
resetMargin: {
|
23
26
|
type: string;
|
24
27
|
};
|
@@ -47,6 +50,9 @@ export declare const Feed: {
|
|
47
50
|
url: {
|
48
51
|
type: string;
|
49
52
|
};
|
53
|
+
urlTitle: {
|
54
|
+
type: string;
|
55
|
+
};
|
50
56
|
};
|
51
57
|
};
|
52
58
|
visible: {
|
@@ -1,9 +1,11 @@
|
|
1
1
|
import React, { useContext, useMemo } from 'react';
|
2
2
|
import { CardBase, HTML, YFMWrapper } from '@gravity-ui/page-constructor';
|
3
|
+
import { useUniqId } from '@gravity-ui/uikit';
|
3
4
|
import { LikesContext } from '../../contexts/LikesContext';
|
4
5
|
import { PostCardSize, PostCardTitleHeadingLevel } from '../../models/common';
|
5
6
|
import { block } from '../../utils/cn';
|
6
7
|
import { SuggestPostInfo } from '../PostInfo/SuggestPostInfo';
|
8
|
+
import { useAriaAttributes } from '../../hooks/useAriaAttributes';
|
7
9
|
import './PostCard.css';
|
8
10
|
const b = block('post-card');
|
9
11
|
export const PostCard = ({ post, metrikaGoals, fullWidth = false, size = PostCardSize.SMALL, showTag = false, titleHeadingLevel = PostCardTitleHeadingLevel.H3, }) => {
|
@@ -18,18 +20,32 @@ export const PostCard = ({ post, metrikaGoals, fullWidth = false, size = PostCar
|
|
18
20
|
toggleLike,
|
19
21
|
}
|
20
22
|
: undefined, [hasUserLike, likes, toggleLike, hasLikes]);
|
21
|
-
|
23
|
+
const titleId = useUniqId();
|
24
|
+
const descriptionId = useUniqId();
|
25
|
+
const dateId = useUniqId();
|
26
|
+
const tagId = useUniqId();
|
27
|
+
const readingTimeId = useUniqId();
|
28
|
+
const isTagVisible = showTag && ((_a = tags === null || tags === void 0 ? void 0 : tags[0]) === null || _a === void 0 ? void 0 : _a.name);
|
29
|
+
const ariaAttributes = useAriaAttributes({
|
30
|
+
labelIds: [isTagVisible && tagId, title && titleId],
|
31
|
+
descriptionIds: [
|
32
|
+
description && descriptionId,
|
33
|
+
date && dateId,
|
34
|
+
readingTime && readingTimeId,
|
35
|
+
],
|
36
|
+
});
|
37
|
+
return (React.createElement(CardBase, { url: url, metrikaGoals: metrikaGoals, className: b('card', { fullWidth }), extraProps: ariaAttributes },
|
22
38
|
React.createElement(CardBase.Header, { image: image, className: b('header', { fullWidth }) },
|
23
39
|
React.createElement("div", { className: b('image-container'), "data-qa": "blog-suggest-header" })),
|
24
40
|
React.createElement(CardBase.Content, null,
|
25
|
-
|
41
|
+
isTagVisible && (React.createElement("div", { id: tagId, className: b('tag', { size }) }, tags[0].name)),
|
26
42
|
title &&
|
27
43
|
React.createElement(titleHeadingLevel, { className: b('title', { size }) }, React.createElement("span", null,
|
28
|
-
React.createElement(HTML,
|
44
|
+
React.createElement(HTML, { id: titleId }, title))),
|
29
45
|
description && (React.createElement(YFMWrapper, { className: b('description'), content: description, modifiers: {
|
30
46
|
blog: size === 'm',
|
31
47
|
blogCard: true,
|
32
|
-
} }))),
|
48
|
+
}, id: descriptionId }))),
|
33
49
|
React.createElement(CardBase.Footer, null,
|
34
|
-
React.createElement(SuggestPostInfo, { postId: blogPostId || id, date: date, readingTime: readingTime, hasUserLike: hasUserLike, likes: likesProps, size: size, qa: "blog-suggest-block" }))));
|
50
|
+
React.createElement(SuggestPostInfo, { postId: blogPostId || id, date: date, readingTime: readingTime, hasUserLike: hasUserLike, likes: likesProps, size: size, qa: "blog-suggest-block", dateId: dateId, readingTimeId: readingTimeId }))));
|
35
51
|
};
|
@@ -9,6 +9,8 @@ export interface SuggestPostInfoProps extends Pick<PostData, 'date' | 'readingTi
|
|
9
9
|
hasUserLike?: boolean;
|
10
10
|
toggleLike?: ToggleLikeCallbackType;
|
11
11
|
};
|
12
|
+
dateId?: string;
|
13
|
+
readingTimeId?: string;
|
12
14
|
}
|
13
15
|
/**
|
14
16
|
* Suggest blog card info component
|
@@ -21,7 +23,9 @@ export interface SuggestPostInfoProps extends Pick<PostData, 'date' | 'readingTi
|
|
21
23
|
* @param qa - test-attr
|
22
24
|
* @param size - text size
|
23
25
|
* @param isModernIcon - flag what we need render 'bookmark' icon
|
26
|
+
* @param dateId - id value for element with post date. Useful when providing accessible description
|
27
|
+
* @param readingTimeId - id value for element with reading time. Useful when providing accessible description
|
24
28
|
*
|
25
29
|
* @returns jsx
|
26
30
|
*/
|
27
|
-
export declare const SuggestPostInfo: ({ postId, date, readingTime, likes, size, qa, }: SuggestPostInfoProps) => React.JSX.Element;
|
31
|
+
export declare const SuggestPostInfo: ({ postId, date, readingTime, likes, size, qa, dateId, readingTimeId, }: SuggestPostInfoProps) => React.JSX.Element;
|
@@ -18,10 +18,12 @@ const b = block('post-info');
|
|
18
18
|
* @param qa - test-attr
|
19
19
|
* @param size - text size
|
20
20
|
* @param isModernIcon - flag what we need render 'bookmark' icon
|
21
|
+
* @param dateId - id value for element with post date. Useful when providing accessible description
|
22
|
+
* @param readingTimeId - id value for element with reading time. Useful when providing accessible description
|
21
23
|
*
|
22
24
|
* @returns jsx
|
23
25
|
*/
|
24
|
-
export const SuggestPostInfo = ({ postId, date, readingTime, likes, size = PostCardSize.SMALL, qa, }) => {
|
26
|
+
export const SuggestPostInfo = ({ postId, date, readingTime, likes, size = PostCardSize.SMALL, qa, dateId, readingTimeId, }) => {
|
25
27
|
const { hasUserLike, likesCount, handleLike } = useLikes({
|
26
28
|
hasLike: likes === null || likes === void 0 ? void 0 : likes.hasUserLike,
|
27
29
|
count: likes === null || likes === void 0 ? void 0 : likes.likesCount,
|
@@ -30,7 +32,7 @@ export const SuggestPostInfo = ({ postId, date, readingTime, likes, size = PostC
|
|
30
32
|
});
|
31
33
|
return (React.createElement("div", { className: b('container') },
|
32
34
|
React.createElement("div", { className: b('suggest-container') },
|
33
|
-
date && React.createElement(Date, { date: date, size: size }),
|
34
|
-
readingTime && React.createElement(ReadingTime, { readingTime: readingTime, size: size })),
|
35
|
+
date && React.createElement(Date, { date: date, size: size, id: dateId }),
|
36
|
+
readingTime && (React.createElement(ReadingTime, { readingTime: readingTime, size: size, id: readingTimeId }))),
|
35
37
|
likes && postId && (React.createElement(Save, { postId: postId, title: likesCount, hasUserLike: hasUserLike, handleUserLike: handleLike, size: size, qa: qa }))));
|
36
38
|
};
|
@@ -4,6 +4,7 @@ import '../PostInfo.css';
|
|
4
4
|
type DateProps = {
|
5
5
|
date: string | number;
|
6
6
|
size?: PostCardSize;
|
7
|
+
id?: string;
|
7
8
|
};
|
8
|
-
export declare const Date: ({ date, size }: DateProps) => React.JSX.Element;
|
9
|
+
export declare const Date: ({ date, size, id }: DateProps) => React.JSX.Element;
|
9
10
|
export {};
|
@@ -5,7 +5,7 @@ import { block } from '../../../utils/cn';
|
|
5
5
|
import { format } from '../../../utils/date';
|
6
6
|
import '../PostInfo.css';
|
7
7
|
const b = block('post-info');
|
8
|
-
export const Date = ({ date, size = PostCardSize.SMALL }) => {
|
8
|
+
export const Date = ({ date, size = PostCardSize.SMALL, id }) => {
|
9
9
|
const { locale } = useContext(LocaleContext);
|
10
|
-
return React.createElement("div", { className: b('item', { size }) }, format(date, 'longDate', locale === null || locale === void 0 ? void 0 : locale.code));
|
10
|
+
return (React.createElement("div", { className: b('item', { size }), id: id }, format(date, 'longDate', locale === null || locale === void 0 ? void 0 : locale.code)));
|
11
11
|
};
|
@@ -3,6 +3,7 @@ import '../PostInfo.css';
|
|
3
3
|
type ReadingTimeProps = {
|
4
4
|
readingTime: number;
|
5
5
|
size?: 's' | 'm';
|
6
|
+
id?: string;
|
6
7
|
};
|
7
|
-
export declare const ReadingTime: ({ readingTime, size }: ReadingTimeProps) => React.JSX.Element;
|
8
|
+
export declare const ReadingTime: ({ readingTime, size, id }: ReadingTimeProps) => React.JSX.Element;
|
8
9
|
export {};
|
@@ -6,7 +6,7 @@ import { block } from '../../../utils/cn';
|
|
6
6
|
import '../PostInfo.css';
|
7
7
|
const b = block('post-info');
|
8
8
|
const ICON_SIZE = 16;
|
9
|
-
export const ReadingTime = ({ readingTime, size = 's' }) => (React.createElement("div", { className: b('item', { size }) },
|
9
|
+
export const ReadingTime = ({ readingTime, size = 's', id }) => (React.createElement("div", { className: b('item', { size }), id: id },
|
10
10
|
React.createElement("span", { className: b('icon') },
|
11
11
|
React.createElement(Icon, { data: Time, size: ICON_SIZE, className: b('icon-color') })),
|
12
12
|
i18(Keyset.ContextReadingTime, { count: readingTime })));
|
@@ -0,0 +1,17 @@
|
|
1
|
+
type Labels = string | number | boolean | undefined;
|
2
|
+
type Description = string | number | boolean | undefined;
|
3
|
+
interface UseAriaAttributesProps {
|
4
|
+
labelIds?: Labels[];
|
5
|
+
descriptionIds: Description[];
|
6
|
+
}
|
7
|
+
/**
|
8
|
+
* Returns aria-attributes
|
9
|
+
* @param labelIds - labels ids. Falsy values will be ignored
|
10
|
+
* @param descriptionIds - descriptions ids. Falsy values will be ignored
|
11
|
+
* @returns aria attributes for the element to be labelled
|
12
|
+
*/
|
13
|
+
export declare const useAriaAttributes: ({ labelIds, descriptionIds }: UseAriaAttributesProps) => {
|
14
|
+
'aria-labelledby': string;
|
15
|
+
'aria-describedby': string;
|
16
|
+
};
|
17
|
+
export {};
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import { useMemo } from 'react';
|
2
|
+
/**
|
3
|
+
* Returns aria-attributes
|
4
|
+
* @param labelIds - labels ids. Falsy values will be ignored
|
5
|
+
* @param descriptionIds - descriptions ids. Falsy values will be ignored
|
6
|
+
* @returns aria attributes for the element to be labelled
|
7
|
+
*/
|
8
|
+
export const useAriaAttributes = ({ labelIds = [], descriptionIds = [] }) => {
|
9
|
+
const labelledBy = useMemo(() => labelIds.filter(Boolean).join(' '), [labelIds]);
|
10
|
+
const describedBy = useMemo(() => descriptionIds.filter(Boolean).join(' '), [descriptionIds]);
|
11
|
+
return {
|
12
|
+
'aria-labelledby': labelledBy,
|
13
|
+
'aria-describedby': describedBy,
|
14
|
+
};
|
15
|
+
};
|
@@ -519,6 +519,9 @@ export declare const schemasForCustom: {
|
|
519
519
|
url: {
|
520
520
|
type: string;
|
521
521
|
};
|
522
|
+
urlTitle: {
|
523
|
+
type: string;
|
524
|
+
};
|
522
525
|
};
|
523
526
|
};
|
524
527
|
visible: {
|
@@ -579,6 +582,9 @@ export declare const schemasForCustom: {
|
|
579
582
|
url: {
|
580
583
|
type: string;
|
581
584
|
};
|
585
|
+
urlTitle: {
|
586
|
+
type: string;
|
587
|
+
};
|
582
588
|
};
|
583
589
|
};
|
584
590
|
visible: {
|
@@ -636,6 +642,9 @@ export declare const schemasForCustom: {
|
|
636
642
|
url: {
|
637
643
|
type: string;
|
638
644
|
};
|
645
|
+
urlTitle: {
|
646
|
+
type: string;
|
647
|
+
};
|
639
648
|
resetMargin: {
|
640
649
|
type: string;
|
641
650
|
};
|
@@ -723,6 +732,9 @@ export declare const schemasForCustom: {
|
|
723
732
|
url: {
|
724
733
|
type: string;
|
725
734
|
};
|
735
|
+
urlTitle: {
|
736
|
+
type: string;
|
737
|
+
};
|
726
738
|
};
|
727
739
|
};
|
728
740
|
visible: {
|
@@ -797,6 +809,9 @@ export declare const schemasForCustom: {
|
|
797
809
|
url: {
|
798
810
|
type: string;
|
799
811
|
};
|
812
|
+
urlTitle: {
|
813
|
+
type: string;
|
814
|
+
};
|
800
815
|
resetMargin: {
|
801
816
|
type: string;
|
802
817
|
};
|
@@ -884,6 +899,9 @@ export declare const schemasForCustom: {
|
|
884
899
|
url: {
|
885
900
|
type: string;
|
886
901
|
};
|
902
|
+
urlTitle: {
|
903
|
+
type: string;
|
904
|
+
};
|
887
905
|
};
|
888
906
|
};
|
889
907
|
visible: {
|
@@ -938,6 +956,9 @@ export declare const schemasForCustom: {
|
|
938
956
|
url: {
|
939
957
|
type: string;
|
940
958
|
};
|
959
|
+
urlTitle: {
|
960
|
+
type: string;
|
961
|
+
};
|
941
962
|
resetMargin: {
|
942
963
|
type: string;
|
943
964
|
};
|
@@ -1028,6 +1049,9 @@ export declare const schemasForCustom: {
|
|
1028
1049
|
url: {
|
1029
1050
|
type: string;
|
1030
1051
|
};
|
1052
|
+
urlTitle: {
|
1053
|
+
type: string;
|
1054
|
+
};
|
1031
1055
|
};
|
1032
1056
|
};
|
1033
1057
|
visible: {
|
@@ -1068,6 +1092,9 @@ export declare const schemasForCustom: {
|
|
1068
1092
|
url: {
|
1069
1093
|
type: string;
|
1070
1094
|
};
|
1095
|
+
urlTitle: {
|
1096
|
+
type: string;
|
1097
|
+
};
|
1071
1098
|
resetMargin: {
|
1072
1099
|
type: string;
|
1073
1100
|
};
|
@@ -1096,6 +1123,9 @@ export declare const schemasForCustom: {
|
|
1096
1123
|
url: {
|
1097
1124
|
type: string;
|
1098
1125
|
};
|
1126
|
+
urlTitle: {
|
1127
|
+
type: string;
|
1128
|
+
};
|
1099
1129
|
};
|
1100
1130
|
};
|
1101
1131
|
visible: {
|
@@ -1161,6 +1191,9 @@ export declare const schemasForCustom: {
|
|
1161
1191
|
url: {
|
1162
1192
|
type: string;
|
1163
1193
|
};
|
1194
|
+
urlTitle: {
|
1195
|
+
type: string;
|
1196
|
+
};
|
1164
1197
|
};
|
1165
1198
|
};
|
1166
1199
|
visible: {
|
@@ -1461,6 +1494,9 @@ export declare const schemasForCustom: {
|
|
1461
1494
|
url: {
|
1462
1495
|
type: string;
|
1463
1496
|
};
|
1497
|
+
urlTitle: {
|
1498
|
+
type: string;
|
1499
|
+
};
|
1464
1500
|
};
|
1465
1501
|
};
|
1466
1502
|
visible: {
|
@@ -1515,6 +1551,9 @@ export declare const schemasForCustom: {
|
|
1515
1551
|
url: {
|
1516
1552
|
type: string;
|
1517
1553
|
};
|
1554
|
+
urlTitle: {
|
1555
|
+
type: string;
|
1556
|
+
};
|
1518
1557
|
};
|
1519
1558
|
};
|
1520
1559
|
visible: {
|
@@ -1569,6 +1608,9 @@ export declare const schemasForCustom: {
|
|
1569
1608
|
url: {
|
1570
1609
|
type: string;
|
1571
1610
|
};
|
1611
|
+
urlTitle: {
|
1612
|
+
type: string;
|
1613
|
+
};
|
1572
1614
|
};
|
1573
1615
|
};
|
1574
1616
|
visible: {
|
@@ -1628,6 +1670,9 @@ export declare const schemasForCustom: {
|
|
1628
1670
|
url: {
|
1629
1671
|
type: string;
|
1630
1672
|
};
|
1673
|
+
urlTitle: {
|
1674
|
+
type: string;
|
1675
|
+
};
|
1631
1676
|
};
|
1632
1677
|
};
|
1633
1678
|
visible: {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@gravity-ui/blog-constructor",
|
3
|
-
"version": "5.8.0
|
3
|
+
"version": "5.8.0",
|
4
4
|
"description": "Gravity UI Blog Constructor",
|
5
5
|
"license": "MIT",
|
6
6
|
"repository": {
|
@@ -66,7 +66,6 @@
|
|
66
66
|
"react-helmet": "^6.1.0",
|
67
67
|
"react-player": "^2.9.0",
|
68
68
|
"react-slick": "^0.29.0",
|
69
|
-
"react-spring": "^9.7.2",
|
70
69
|
"react-transition-group": "^4.4.2",
|
71
70
|
"react-waypoint": "^10.1.0",
|
72
71
|
"sanitize-html": "^2.6.1",
|
@@ -79,7 +78,7 @@
|
|
79
78
|
},
|
80
79
|
"peerDependencies": {
|
81
80
|
"@doc-tools/transform": "^3.3.2",
|
82
|
-
"@gravity-ui/page-constructor": "^4.
|
81
|
+
"@gravity-ui/page-constructor": "^4.31.0",
|
83
82
|
"@gravity-ui/uikit": "^5.12.0",
|
84
83
|
"react": "^16.0.0 || ^17.0.0 || ^18.0.0"
|
85
84
|
},
|
@@ -90,7 +89,7 @@
|
|
90
89
|
"@commitlint/config-conventional": "^17.4.3",
|
91
90
|
"@doc-tools/transform": "^3.11.0",
|
92
91
|
"@gravity-ui/eslint-config": "^3.1.1",
|
93
|
-
"@gravity-ui/page-constructor": "^4.
|
92
|
+
"@gravity-ui/page-constructor": "^4.31.0",
|
94
93
|
"@gravity-ui/prettier-config": "^1.1.0",
|
95
94
|
"@gravity-ui/stylelint-config": "^4.0.1",
|
96
95
|
"@gravity-ui/tsconfig": "^1.0.0",
|