@gravity-ui/blog-constructor 3.4.1 → 3.5.0-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/build/cjs/components/PostInfo/components/Save.js +6 -1
- package/build/cjs/components/Prompt/Prompt.css +61 -0
- package/build/cjs/components/Prompt/Prompt.d.ts +18 -0
- package/build/cjs/components/Prompt/Prompt.js +41 -0
- package/build/cjs/components/PromptSignIn/PromptSignIn.d.ts +10 -0
- package/build/cjs/components/PromptSignIn/PromptSignIn.js +34 -0
- package/build/cjs/components/PromptSignIn/hooks/usePromptSignInProps.d.ts +6 -0
- package/build/cjs/components/PromptSignIn/hooks/usePromptSignInProps.js +16 -0
- package/build/cjs/containers/BlogPage/BlogPage.d.ts +4 -1
- package/build/cjs/containers/BlogPage/BlogPage.js +56 -18
- package/build/cjs/contexts/LikesContext.d.ts +2 -0
- package/build/cjs/hooks/useOpenCloseTimer.d.ts +9 -0
- package/build/cjs/hooks/useOpenCloseTimer.js +30 -0
- package/build/cjs/i18n/index.d.ts +3 -1
- package/build/cjs/i18n/index.js +6 -0
- package/build/esm/components/PostInfo/components/Save.js +6 -1
- package/build/esm/components/Prompt/Prompt.css +61 -0
- package/build/esm/components/Prompt/Prompt.d.ts +19 -0
- package/build/esm/components/Prompt/Prompt.js +35 -0
- package/build/esm/components/PromptSignIn/PromptSignIn.d.ts +10 -0
- package/build/esm/components/PromptSignIn/PromptSignIn.js +27 -0
- package/build/esm/components/PromptSignIn/hooks/usePromptSignInProps.d.ts +6 -0
- package/build/esm/components/PromptSignIn/hooks/usePromptSignInProps.js +12 -0
- package/build/esm/containers/BlogPage/BlogPage.d.ts +4 -1
- package/build/esm/containers/BlogPage/BlogPage.js +33 -18
- package/build/esm/contexts/LikesContext.d.ts +2 -0
- package/build/esm/hooks/useOpenCloseTimer.d.ts +9 -0
- package/build/esm/hooks/useOpenCloseTimer.js +26 -0
- package/build/esm/i18n/index.d.ts +3 -1
- package/build/esm/i18n/index.js +6 -0
- package/package.json +4 -1
@@ -53,7 +53,7 @@ const b = (0, cn_1.block)('post-info');
|
|
53
53
|
* @returns jsx
|
54
54
|
*/
|
55
55
|
const Save = ({ title, postId, hasUserLike, handleUserLike, metrikaGoal, size, theme, dataQa, }) => {
|
56
|
-
const { toggleLike } = (0, react_1.useContext)(LikesContext_1.LikesContext);
|
56
|
+
const { toggleLike, isSignedInUser, requireSignIn } = (0, react_1.useContext)(LikesContext_1.LikesContext);
|
57
57
|
const handleAnalytics = (0, page_constructor_1.useAnalytics)(common_1.DefaultEventNames.SaveButton);
|
58
58
|
const isLikeable = Boolean(toggleLike);
|
59
59
|
return (react_1.default.createElement("div", { className: b('item', { size }), onClick: (event) => {
|
@@ -64,6 +64,11 @@ const Save = ({ title, postId, hasUserLike, handleUserLike, metrikaGoal, size, t
|
|
64
64
|
if (!isLikeable) {
|
65
65
|
return;
|
66
66
|
}
|
67
|
+
// Open Popup to ask the User to sign in first
|
68
|
+
if (!isSignedInUser && requireSignIn) {
|
69
|
+
requireSignIn(event);
|
70
|
+
return;
|
71
|
+
}
|
67
72
|
(0, common_2.postLikeStatus)(postId, Boolean(hasUserLike));
|
68
73
|
handleUserLike();
|
69
74
|
metrika_js_1.default.reachGoal(utils_1.MetrikaCounter.CrossSite, metrikaGoal);
|
@@ -0,0 +1,61 @@
|
|
1
|
+
.bc-prompt__content {
|
2
|
+
box-shadow: 0px 4px 24px var(--pc-color-sfx-shadow), 0px 2px 8px var(--pc-color-sfx-shadow);
|
3
|
+
}
|
4
|
+
|
5
|
+
/* use this for style redefinitions to awoid problems with
|
6
|
+
unpredictable css rules order in build */
|
7
|
+
@keyframes bc-prompt_open {
|
8
|
+
0% {
|
9
|
+
opacity: 0;
|
10
|
+
transform: translateY(100%);
|
11
|
+
}
|
12
|
+
100% {
|
13
|
+
opacity: 1;
|
14
|
+
transform: translateY(0%);
|
15
|
+
}
|
16
|
+
}
|
17
|
+
@keyframes bc-prompt_close {
|
18
|
+
0% {
|
19
|
+
opacity: 1;
|
20
|
+
transform: translateY(0%);
|
21
|
+
}
|
22
|
+
100% {
|
23
|
+
opacity: 0;
|
24
|
+
transform: translateY(100%);
|
25
|
+
}
|
26
|
+
}
|
27
|
+
.bc-prompt {
|
28
|
+
display: flex;
|
29
|
+
width: 100%;
|
30
|
+
justify-content: center;
|
31
|
+
overflow: hidden;
|
32
|
+
position: fixed;
|
33
|
+
bottom: 0;
|
34
|
+
}
|
35
|
+
.bc-prompt:not(.bc-prompt_mounted) {
|
36
|
+
display: none;
|
37
|
+
}
|
38
|
+
.bc-prompt__content {
|
39
|
+
display: flex;
|
40
|
+
flex-flow: row wrap;
|
41
|
+
gap: 16px;
|
42
|
+
align-items: center;
|
43
|
+
margin: 24px;
|
44
|
+
padding: 16px 20px;
|
45
|
+
border-radius: var(--pc-border-radius);
|
46
|
+
background-color: var(--yc-color-base-float);
|
47
|
+
font-size: 1rem;
|
48
|
+
}
|
49
|
+
.bc-prompt_close {
|
50
|
+
pointer-events: none;
|
51
|
+
}
|
52
|
+
.bc-prompt_open > .bc-prompt__content {
|
53
|
+
opacity: 0;
|
54
|
+
transform: translateY(100%);
|
55
|
+
animation: bc-prompt_open 600ms forwards;
|
56
|
+
}
|
57
|
+
.bc-prompt_close > .bc-prompt__content {
|
58
|
+
opacity: 1;
|
59
|
+
transform: translateY(0%);
|
60
|
+
animation: bc-prompt_close 600ms forwards;
|
61
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { ButtonProps } from '@gravity-ui/uikit';
|
3
|
+
export interface PromptProps {
|
4
|
+
text: string;
|
5
|
+
actions: ButtonProps[];
|
6
|
+
openTimestamp?: number;
|
7
|
+
openDuration?: number;
|
8
|
+
className?: string;
|
9
|
+
theme?: 'grey' | 'beige' | 'white';
|
10
|
+
}
|
11
|
+
/**
|
12
|
+
* Popup that appears with text message and button(s) for given `actions`.
|
13
|
+
* Features:
|
14
|
+
* - Automatically disappears after `openDuration` in milliseconds
|
15
|
+
* - `openTimestamp` (`Date.now()`) resets the visible duration
|
16
|
+
* @returns {JSX|null}
|
17
|
+
*/
|
18
|
+
export declare const Prompt: React.FC<PromptProps>;
|
@@ -0,0 +1,41 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
3
|
+
var t = {};
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
5
|
+
t[p] = s[p];
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
9
|
+
t[p[i]] = s[p[i]];
|
10
|
+
}
|
11
|
+
return t;
|
12
|
+
};
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
15
|
+
};
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
17
|
+
exports.Prompt = void 0;
|
18
|
+
const react_1 = __importDefault(require("react"));
|
19
|
+
const uikit_1 = require("@gravity-ui/uikit");
|
20
|
+
const useOpenCloseTimer_1 = require("../../hooks/useOpenCloseTimer");
|
21
|
+
const cn_1 = require("../../utils/cn");
|
22
|
+
const b = (0, cn_1.block)('prompt');
|
23
|
+
/**
|
24
|
+
* Popup that appears with text message and button(s) for given `actions`.
|
25
|
+
* Features:
|
26
|
+
* - Automatically disappears after `openDuration` in milliseconds
|
27
|
+
* - `openTimestamp` (`Date.now()`) resets the visible duration
|
28
|
+
* @returns {JSX|null}
|
29
|
+
*/
|
30
|
+
const Prompt = ({ text, actions, className, openTimestamp = 0, openDuration, theme, }) => {
|
31
|
+
const { open } = (0, useOpenCloseTimer_1.useOpenCloseTimer)(openTimestamp, openDuration);
|
32
|
+
const mounted = openTimestamp > 0;
|
33
|
+
return (react_1.default.createElement("div", { className: b({ theme, open, close: !open, mounted }, className) },
|
34
|
+
react_1.default.createElement("div", { className: b('content') },
|
35
|
+
react_1.default.createElement("span", { className: b('text') }, text),
|
36
|
+
react_1.default.createElement("div", { className: b('actions') }, actions.map((_a, i) => {
|
37
|
+
var { view = 'action', className: btnClass } = _a, btnProps = __rest(_a, ["view", "className"]);
|
38
|
+
return (react_1.default.createElement(uikit_1.Button, Object.assign({ key: i, className: b('action', btnClass), view: view }, btnProps)));
|
39
|
+
})))));
|
40
|
+
};
|
41
|
+
exports.Prompt = Prompt;
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import React, { SyntheticEvent } from 'react';
|
2
|
+
import { PromptProps } from '../Prompt/Prompt';
|
3
|
+
export interface PromptSignInProps extends Partial<PromptProps> {
|
4
|
+
onClickSignIn?: React.EventHandler<SyntheticEvent>;
|
5
|
+
}
|
6
|
+
/**
|
7
|
+
* Authentication Popup that appears when user action requires login
|
8
|
+
* @returns {JSX|null}
|
9
|
+
*/
|
10
|
+
export declare const PromptSignIn: React.FC<PromptSignInProps>;
|
@@ -0,0 +1,34 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
3
|
+
var t = {};
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
5
|
+
t[p] = s[p];
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
9
|
+
t[p[i]] = s[p[i]];
|
10
|
+
}
|
11
|
+
return t;
|
12
|
+
};
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
15
|
+
};
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
17
|
+
exports.PromptSignIn = void 0;
|
18
|
+
const react_1 = __importDefault(require("react"));
|
19
|
+
const i18n_1 = require("../../i18n");
|
20
|
+
const Prompt_1 = require("../Prompt/Prompt");
|
21
|
+
/**
|
22
|
+
* Authentication Popup that appears when user action requires login
|
23
|
+
* @returns {JSX|null}
|
24
|
+
*/
|
25
|
+
const PromptSignIn = (_a) => {
|
26
|
+
var { text = (0, i18n_1.i18)(i18n_1.Keyset.PromptSignInOnLike), onClickSignIn = () => alert((0, i18n_1.i18)(i18n_1.Keyset.SignIn)), actions = [
|
27
|
+
{
|
28
|
+
children: (0, i18n_1.i18)(i18n_1.Keyset.SignIn),
|
29
|
+
onClick: onClickSignIn,
|
30
|
+
},
|
31
|
+
] } = _a, props = __rest(_a, ["text", "onClickSignIn", "actions"]);
|
32
|
+
return react_1.default.createElement(Prompt_1.Prompt, Object.assign({}, { text, actions }, props));
|
33
|
+
};
|
34
|
+
exports.PromptSignIn = PromptSignIn;
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import React, { SyntheticEvent } from 'react';
|
2
|
+
export declare function usePromptSignInProps(onClickSignIn?: React.EventHandler<SyntheticEvent>): {
|
3
|
+
onClickSignIn: ((event: React.SyntheticEvent<Element, Event>) => void) | undefined;
|
4
|
+
openTimestamp: number;
|
5
|
+
requireSignIn: (() => void) | undefined;
|
6
|
+
};
|
@@ -0,0 +1,16 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.usePromptSignInProps = void 0;
|
4
|
+
const react_1 = require("react");
|
5
|
+
function usePromptSignInProps(onClickSignIn) {
|
6
|
+
const [openTimestamp, setTime] = (0, react_1.useState)(0);
|
7
|
+
const requireSignIn = (0, react_1.useMemo)(() => {
|
8
|
+
return onClickSignIn
|
9
|
+
? () => {
|
10
|
+
setTime(Date.now());
|
11
|
+
}
|
12
|
+
: undefined;
|
13
|
+
}, [onClickSignIn, setTime]);
|
14
|
+
return { onClickSignIn, openTimestamp, requireSignIn };
|
15
|
+
}
|
16
|
+
exports.usePromptSignInProps = usePromptSignInProps;
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import React, { SyntheticEvent } from 'react';
|
1
2
|
import { NavigationData, PageConstructorProviderProps, PageContent } from '@gravity-ui/page-constructor';
|
2
3
|
import { GetPostsType, MetaProps, PostsProps, Service, SetQueryType, Tag, ToggleLikeCallbackType } from '../../models/common';
|
3
4
|
export type BlogPageProps = {
|
@@ -13,5 +14,7 @@ export type BlogPageProps = {
|
|
13
14
|
setQuery?: SetQueryType;
|
14
15
|
settings?: PageConstructorProviderProps;
|
15
16
|
pageCountForShowSupportButtons?: number;
|
17
|
+
isSignedInUser?: boolean;
|
18
|
+
onClickSignIn?: React.EventHandler<SyntheticEvent>;
|
16
19
|
};
|
17
|
-
export declare const BlogPage: ({ content, posts, tags, services, getPosts, metaData, hasLikes, toggleLike, navigation, settings, pageCountForShowSupportButtons, }: BlogPageProps) => JSX.Element;
|
20
|
+
export declare const BlogPage: ({ content, posts, tags, services, getPosts, metaData, hasLikes, toggleLike, navigation, settings, pageCountForShowSupportButtons, isSignedInUser, onClickSignIn, }: BlogPageProps) => JSX.Element;
|
@@ -1,30 +1,68 @@
|
|
1
1
|
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15
|
+
}) : function(o, v) {
|
16
|
+
o["default"] = v;
|
17
|
+
});
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
19
|
+
if (mod && mod.__esModule) return mod;
|
20
|
+
var result = {};
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
22
|
+
__setModuleDefault(result, mod);
|
23
|
+
return result;
|
24
|
+
};
|
25
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
26
|
+
var t = {};
|
27
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
28
|
+
t[p] = s[p];
|
29
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
30
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
31
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
32
|
+
t[p[i]] = s[p[i]];
|
33
|
+
}
|
34
|
+
return t;
|
35
|
+
};
|
2
36
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
37
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
38
|
};
|
5
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
40
|
exports.BlogPage = void 0;
|
7
|
-
const react_1 =
|
41
|
+
const react_1 = __importStar(require("react"));
|
8
42
|
const page_constructor_1 = require("@gravity-ui/page-constructor");
|
9
43
|
const MetaWrapper_1 = require("../../components/MetaWrapper/MetaWrapper");
|
44
|
+
const PromptSignIn_1 = require("../../components/PromptSignIn/PromptSignIn");
|
45
|
+
const usePromptSignInProps_1 = require("../../components/PromptSignIn/hooks/usePromptSignInProps");
|
10
46
|
const blocksMap_1 = __importDefault(require("../../constructor/blocksMap"));
|
11
47
|
const FeedContext_1 = require("../../contexts/FeedContext");
|
12
48
|
const LikesContext_1 = require("../../contexts/LikesContext");
|
13
|
-
const BlogPage = ({ content, posts, tags, services, getPosts, metaData, hasLikes = false, toggleLike, navigation, settings, pageCountForShowSupportButtons, }) =>
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
49
|
+
const BlogPage = ({ content, posts, tags, services, getPosts, metaData, hasLikes = false, toggleLike, navigation, settings, pageCountForShowSupportButtons, isSignedInUser = false, onClickSignIn, }) => {
|
50
|
+
const _a = (0, usePromptSignInProps_1.usePromptSignInProps)(onClickSignIn), { requireSignIn } = _a, promptSignInProps = __rest(_a, ["requireSignIn"]);
|
51
|
+
const likes = (0, react_1.useMemo)(() => ({ toggleLike, hasLikes, isSignedInUser, requireSignIn }), [toggleLike, hasLikes, isSignedInUser, requireSignIn]);
|
52
|
+
return (react_1.default.createElement("main", null,
|
53
|
+
react_1.default.createElement(LikesContext_1.LikesContext.Provider, { value: likes },
|
54
|
+
react_1.default.createElement(FeedContext_1.FeedContext.Provider, { value: {
|
55
|
+
posts: posts.posts,
|
56
|
+
pinnedPost: posts.pinnedPost,
|
57
|
+
totalCount: posts.count,
|
58
|
+
tags,
|
59
|
+
services: services !== null && services !== void 0 ? services : [],
|
60
|
+
getPosts,
|
61
|
+
pageCountForShowSupportButtons,
|
62
|
+
} },
|
63
|
+
react_1.default.createElement(page_constructor_1.PageConstructorProvider, Object.assign({}, settings),
|
64
|
+
metaData ? react_1.default.createElement(MetaWrapper_1.MetaWrapper, Object.assign({}, metaData)) : null,
|
65
|
+
react_1.default.createElement(page_constructor_1.PageConstructor, { content: content, custom: blocksMap_1.default, navigation: navigation })))),
|
66
|
+
react_1.default.createElement(PromptSignIn_1.PromptSignIn, Object.assign({}, promptSignInProps))));
|
67
|
+
};
|
30
68
|
exports.BlogPage = BlogPage;
|
@@ -3,5 +3,7 @@ import { ToggleLikeCallbackType } from '../models/common';
|
|
3
3
|
export interface LikesContextProps {
|
4
4
|
toggleLike?: ToggleLikeCallbackType;
|
5
5
|
hasLikes?: boolean;
|
6
|
+
isSignedInUser?: boolean;
|
7
|
+
requireSignIn?: React.MouseEventHandler;
|
6
8
|
}
|
7
9
|
export declare const LikesContext: React.Context<LikesContextProps>;
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/**
|
2
|
+
* Timer to automatically update `open` state after a given duration
|
3
|
+
* @param {number} openTimestamp - UNIX timestamp in milliseconds
|
4
|
+
* @param {number} openDuration - in milliseconds
|
5
|
+
* @returns {{open: boolean}} {open} - whether the state is open
|
6
|
+
*/
|
7
|
+
export declare function useOpenCloseTimer(openTimestamp?: number, openDuration?: number): {
|
8
|
+
open: boolean;
|
9
|
+
};
|
@@ -0,0 +1,30 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.useOpenCloseTimer = void 0;
|
4
|
+
const react_1 = require("react");
|
5
|
+
/**
|
6
|
+
* Timer to automatically update `open` state after a given duration
|
7
|
+
* @param {number} openTimestamp - UNIX timestamp in milliseconds
|
8
|
+
* @param {number} openDuration - in milliseconds
|
9
|
+
* @returns {{open: boolean}} {open} - whether the state is open
|
10
|
+
*/
|
11
|
+
function useOpenCloseTimer(openTimestamp = Date.now(), openDuration = 4000) {
|
12
|
+
const open = Date.now() - openTimestamp < openDuration;
|
13
|
+
const [, reset] = (0, react_1.useState)(0); // time to reset `open` state
|
14
|
+
(0, react_1.useEffect)(() => {
|
15
|
+
const closeTime = openTimestamp + openDuration;
|
16
|
+
const delay = closeTime - Date.now();
|
17
|
+
if (delay <= 0) {
|
18
|
+
return;
|
19
|
+
}
|
20
|
+
const timer = setTimeout(() => {
|
21
|
+
reset(Date.now);
|
22
|
+
}, delay);
|
23
|
+
// eslint-disable-next-line consistent-return
|
24
|
+
return () => {
|
25
|
+
clearTimeout(timer);
|
26
|
+
};
|
27
|
+
}, [openTimestamp, openDuration]);
|
28
|
+
return { open };
|
29
|
+
}
|
30
|
+
exports.useOpenCloseTimer = useOpenCloseTimer;
|
@@ -17,6 +17,8 @@ export declare enum Keyset {
|
|
17
17
|
Search = "search_placeholder",
|
18
18
|
AllTags = "label_all_tags",
|
19
19
|
ActionSavedOnly = "action_saved_only",
|
20
|
-
AllServices = "label_all_services"
|
20
|
+
AllServices = "label_all_services",
|
21
|
+
PromptSignInOnLike = "prompt_sign_in_on_like",
|
22
|
+
SignIn = "Sign In"
|
21
23
|
}
|
22
24
|
export declare const i18: (key: string, params?: import("@gravity-ui/i18n").Params | undefined) => string;
|
package/build/cjs/i18n/index.js
CHANGED
@@ -24,6 +24,8 @@ var Keyset;
|
|
24
24
|
Keyset["AllTags"] = "label_all_tags";
|
25
25
|
Keyset["ActionSavedOnly"] = "action_saved_only";
|
26
26
|
Keyset["AllServices"] = "label_all_services";
|
27
|
+
Keyset["PromptSignInOnLike"] = "prompt_sign_in_on_like";
|
28
|
+
Keyset["SignIn"] = "Sign In";
|
27
29
|
})(Keyset = exports.Keyset || (exports.Keyset = {}));
|
28
30
|
exports.i18n.registerKeyset(locale_1.Lang.En, KEYSET_NAME, {
|
29
31
|
[Keyset.Title]: 'Blog',
|
@@ -42,11 +44,13 @@ exports.i18n.registerKeyset(locale_1.Lang.En, KEYSET_NAME, {
|
|
42
44
|
[Keyset.AllTags]: 'All topics',
|
43
45
|
[Keyset.ActionSavedOnly]: 'Saved',
|
44
46
|
[Keyset.AllServices]: 'All Services',
|
47
|
+
[Keyset.PromptSignInOnLike]: 'Please sign in to save your bookmarks',
|
45
48
|
[Keyset.ContextReadingTime]: [
|
46
49
|
'{{count}} min to read',
|
47
50
|
'{{count}} mins to read',
|
48
51
|
'{{count}} mins to read',
|
49
52
|
],
|
53
|
+
[Keyset.SignIn]: 'Sign In',
|
50
54
|
});
|
51
55
|
exports.i18n.registerKeyset(locale_1.Lang.Ru, KEYSET_NAME, {
|
52
56
|
[Keyset.Title]: 'Блог',
|
@@ -65,10 +69,12 @@ exports.i18n.registerKeyset(locale_1.Lang.Ru, KEYSET_NAME, {
|
|
65
69
|
[Keyset.AllTags]: 'Все темы',
|
66
70
|
[Keyset.ActionSavedOnly]: 'Сохранённые',
|
67
71
|
[Keyset.AllServices]: 'Все сервисы',
|
72
|
+
[Keyset.PromptSignInOnLike]: 'Войдите, чтобы добавить доклад в своё расписание',
|
68
73
|
[Keyset.ContextReadingTime]: [
|
69
74
|
'{{count}} минута чтения',
|
70
75
|
'{{count}} минуты чтения',
|
71
76
|
'{{count}} минут чтения',
|
72
77
|
],
|
78
|
+
[Keyset.SignIn]: 'Войти',
|
73
79
|
});
|
74
80
|
exports.i18 = exports.i18n.keyset(KEYSET_NAME);
|
@@ -25,7 +25,7 @@ const b = block('post-info');
|
|
25
25
|
* @returns jsx
|
26
26
|
*/
|
27
27
|
export const Save = ({ title, postId, hasUserLike, handleUserLike, metrikaGoal, size, theme, dataQa, }) => {
|
28
|
-
const { toggleLike } = useContext(LikesContext);
|
28
|
+
const { toggleLike, isSignedInUser, requireSignIn } = useContext(LikesContext);
|
29
29
|
const handleAnalytics = useAnalytics(DefaultEventNames.SaveButton);
|
30
30
|
const isLikeable = Boolean(toggleLike);
|
31
31
|
return (React.createElement("div", { className: b('item', { size }), onClick: (event) => {
|
@@ -36,6 +36,11 @@ export const Save = ({ title, postId, hasUserLike, handleUserLike, metrikaGoal,
|
|
36
36
|
if (!isLikeable) {
|
37
37
|
return;
|
38
38
|
}
|
39
|
+
// Open Popup to ask the User to sign in first
|
40
|
+
if (!isSignedInUser && requireSignIn) {
|
41
|
+
requireSignIn(event);
|
42
|
+
return;
|
43
|
+
}
|
39
44
|
postLikeStatus(postId, Boolean(hasUserLike));
|
40
45
|
handleUserLike();
|
41
46
|
metrika.reachGoal(MetrikaCounter.CrossSite, metrikaGoal);
|
@@ -0,0 +1,61 @@
|
|
1
|
+
.bc-prompt__content {
|
2
|
+
box-shadow: 0px 4px 24px var(--pc-color-sfx-shadow), 0px 2px 8px var(--pc-color-sfx-shadow);
|
3
|
+
}
|
4
|
+
|
5
|
+
/* use this for style redefinitions to awoid problems with
|
6
|
+
unpredictable css rules order in build */
|
7
|
+
@keyframes bc-prompt_open {
|
8
|
+
0% {
|
9
|
+
opacity: 0;
|
10
|
+
transform: translateY(100%);
|
11
|
+
}
|
12
|
+
100% {
|
13
|
+
opacity: 1;
|
14
|
+
transform: translateY(0%);
|
15
|
+
}
|
16
|
+
}
|
17
|
+
@keyframes bc-prompt_close {
|
18
|
+
0% {
|
19
|
+
opacity: 1;
|
20
|
+
transform: translateY(0%);
|
21
|
+
}
|
22
|
+
100% {
|
23
|
+
opacity: 0;
|
24
|
+
transform: translateY(100%);
|
25
|
+
}
|
26
|
+
}
|
27
|
+
.bc-prompt {
|
28
|
+
display: flex;
|
29
|
+
width: 100%;
|
30
|
+
justify-content: center;
|
31
|
+
overflow: hidden;
|
32
|
+
position: fixed;
|
33
|
+
bottom: 0;
|
34
|
+
}
|
35
|
+
.bc-prompt:not(.bc-prompt_mounted) {
|
36
|
+
display: none;
|
37
|
+
}
|
38
|
+
.bc-prompt__content {
|
39
|
+
display: flex;
|
40
|
+
flex-flow: row wrap;
|
41
|
+
gap: 16px;
|
42
|
+
align-items: center;
|
43
|
+
margin: 24px;
|
44
|
+
padding: 16px 20px;
|
45
|
+
border-radius: var(--pc-border-radius);
|
46
|
+
background-color: var(--yc-color-base-float);
|
47
|
+
font-size: 1rem;
|
48
|
+
}
|
49
|
+
.bc-prompt_close {
|
50
|
+
pointer-events: none;
|
51
|
+
}
|
52
|
+
.bc-prompt_open > .bc-prompt__content {
|
53
|
+
opacity: 0;
|
54
|
+
transform: translateY(100%);
|
55
|
+
animation: bc-prompt_open 600ms forwards;
|
56
|
+
}
|
57
|
+
.bc-prompt_close > .bc-prompt__content {
|
58
|
+
opacity: 1;
|
59
|
+
transform: translateY(0%);
|
60
|
+
animation: bc-prompt_close 600ms forwards;
|
61
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { ButtonProps } from '@gravity-ui/uikit';
|
3
|
+
import './Prompt.css';
|
4
|
+
export interface PromptProps {
|
5
|
+
text: string;
|
6
|
+
actions: ButtonProps[];
|
7
|
+
openTimestamp?: number;
|
8
|
+
openDuration?: number;
|
9
|
+
className?: string;
|
10
|
+
theme?: 'grey' | 'beige' | 'white';
|
11
|
+
}
|
12
|
+
/**
|
13
|
+
* Popup that appears with text message and button(s) for given `actions`.
|
14
|
+
* Features:
|
15
|
+
* - Automatically disappears after `openDuration` in milliseconds
|
16
|
+
* - `openTimestamp` (`Date.now()`) resets the visible duration
|
17
|
+
* @returns {JSX|null}
|
18
|
+
*/
|
19
|
+
export declare const Prompt: React.FC<PromptProps>;
|
@@ -0,0 +1,35 @@
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
2
|
+
var t = {};
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
4
|
+
t[p] = s[p];
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
8
|
+
t[p[i]] = s[p[i]];
|
9
|
+
}
|
10
|
+
return t;
|
11
|
+
};
|
12
|
+
import React from 'react';
|
13
|
+
import { Button } from '@gravity-ui/uikit';
|
14
|
+
import { useOpenCloseTimer } from '../../hooks/useOpenCloseTimer';
|
15
|
+
import { block } from '../../utils/cn';
|
16
|
+
import './Prompt.css';
|
17
|
+
const b = block('prompt');
|
18
|
+
/**
|
19
|
+
* Popup that appears with text message and button(s) for given `actions`.
|
20
|
+
* Features:
|
21
|
+
* - Automatically disappears after `openDuration` in milliseconds
|
22
|
+
* - `openTimestamp` (`Date.now()`) resets the visible duration
|
23
|
+
* @returns {JSX|null}
|
24
|
+
*/
|
25
|
+
export const Prompt = ({ text, actions, className, openTimestamp = 0, openDuration, theme, }) => {
|
26
|
+
const { open } = useOpenCloseTimer(openTimestamp, openDuration);
|
27
|
+
const mounted = openTimestamp > 0;
|
28
|
+
return (React.createElement("div", { className: b({ theme, open, close: !open, mounted }, className) },
|
29
|
+
React.createElement("div", { className: b('content') },
|
30
|
+
React.createElement("span", { className: b('text') }, text),
|
31
|
+
React.createElement("div", { className: b('actions') }, actions.map((_a, i) => {
|
32
|
+
var { view = 'action', className: btnClass } = _a, btnProps = __rest(_a, ["view", "className"]);
|
33
|
+
return (React.createElement(Button, Object.assign({ key: i, className: b('action', btnClass), view: view }, btnProps)));
|
34
|
+
})))));
|
35
|
+
};
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import React, { SyntheticEvent } from 'react';
|
2
|
+
import { PromptProps } from '../Prompt/Prompt';
|
3
|
+
export interface PromptSignInProps extends Partial<PromptProps> {
|
4
|
+
onClickSignIn?: React.EventHandler<SyntheticEvent>;
|
5
|
+
}
|
6
|
+
/**
|
7
|
+
* Authentication Popup that appears when user action requires login
|
8
|
+
* @returns {JSX|null}
|
9
|
+
*/
|
10
|
+
export declare const PromptSignIn: React.FC<PromptSignInProps>;
|
@@ -0,0 +1,27 @@
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
2
|
+
var t = {};
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
4
|
+
t[p] = s[p];
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
8
|
+
t[p[i]] = s[p[i]];
|
9
|
+
}
|
10
|
+
return t;
|
11
|
+
};
|
12
|
+
import React from 'react';
|
13
|
+
import { Keyset, i18 } from '../../i18n';
|
14
|
+
import { Prompt } from '../Prompt/Prompt';
|
15
|
+
/**
|
16
|
+
* Authentication Popup that appears when user action requires login
|
17
|
+
* @returns {JSX|null}
|
18
|
+
*/
|
19
|
+
export const PromptSignIn = (_a) => {
|
20
|
+
var { text = i18(Keyset.PromptSignInOnLike), onClickSignIn = () => alert(i18(Keyset.SignIn)), actions = [
|
21
|
+
{
|
22
|
+
children: i18(Keyset.SignIn),
|
23
|
+
onClick: onClickSignIn,
|
24
|
+
},
|
25
|
+
] } = _a, props = __rest(_a, ["text", "onClickSignIn", "actions"]);
|
26
|
+
return React.createElement(Prompt, Object.assign({}, { text, actions }, props));
|
27
|
+
};
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import React, { SyntheticEvent } from 'react';
|
2
|
+
export declare function usePromptSignInProps(onClickSignIn?: React.EventHandler<SyntheticEvent>): {
|
3
|
+
onClickSignIn: ((event: React.SyntheticEvent<Element, Event>) => void) | undefined;
|
4
|
+
openTimestamp: number;
|
5
|
+
requireSignIn: (() => void) | undefined;
|
6
|
+
};
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import { useMemo, useState } from 'react';
|
2
|
+
export function usePromptSignInProps(onClickSignIn) {
|
3
|
+
const [openTimestamp, setTime] = useState(0);
|
4
|
+
const requireSignIn = useMemo(() => {
|
5
|
+
return onClickSignIn
|
6
|
+
? () => {
|
7
|
+
setTime(Date.now());
|
8
|
+
}
|
9
|
+
: undefined;
|
10
|
+
}, [onClickSignIn, setTime]);
|
11
|
+
return { onClickSignIn, openTimestamp, requireSignIn };
|
12
|
+
}
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import React, { SyntheticEvent } from 'react';
|
1
2
|
import { NavigationData, PageConstructorProviderProps, PageContent } from '@gravity-ui/page-constructor';
|
2
3
|
import { GetPostsType, MetaProps, PostsProps, Service, SetQueryType, Tag, ToggleLikeCallbackType } from '../../models/common';
|
3
4
|
import './BlogPage.css';
|
@@ -14,5 +15,7 @@ export type BlogPageProps = {
|
|
14
15
|
setQuery?: SetQueryType;
|
15
16
|
settings?: PageConstructorProviderProps;
|
16
17
|
pageCountForShowSupportButtons?: number;
|
18
|
+
isSignedInUser?: boolean;
|
19
|
+
onClickSignIn?: React.EventHandler<SyntheticEvent>;
|
17
20
|
};
|
18
|
-
export declare const BlogPage: ({ content, posts, tags, services, getPosts, metaData, hasLikes, toggleLike, navigation, settings, pageCountForShowSupportButtons, }: BlogPageProps) => JSX.Element;
|
21
|
+
export declare const BlogPage: ({ content, posts, tags, services, getPosts, metaData, hasLikes, toggleLike, navigation, settings, pageCountForShowSupportButtons, isSignedInUser, onClickSignIn, }: BlogPageProps) => JSX.Element;
|
@@ -1,24 +1,39 @@
|
|
1
|
-
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
2
|
+
var t = {};
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
4
|
+
t[p] = s[p];
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
8
|
+
t[p[i]] = s[p[i]];
|
9
|
+
}
|
10
|
+
return t;
|
11
|
+
};
|
12
|
+
import React, { useMemo } from 'react';
|
2
13
|
import { PageConstructor, PageConstructorProvider, } from '@gravity-ui/page-constructor';
|
3
14
|
import { MetaWrapper } from '../../components/MetaWrapper/MetaWrapper';
|
15
|
+
import { PromptSignIn } from '../../components/PromptSignIn/PromptSignIn';
|
16
|
+
import { usePromptSignInProps } from '../../components/PromptSignIn/hooks/usePromptSignInProps';
|
4
17
|
import componentMap from '../../constructor/blocksMap';
|
5
18
|
import { FeedContext } from '../../contexts/FeedContext';
|
6
19
|
import { LikesContext } from '../../contexts/LikesContext';
|
7
20
|
import './BlogPage.css';
|
8
|
-
export const BlogPage = ({ content, posts, tags, services, getPosts, metaData, hasLikes = false, toggleLike, navigation, settings, pageCountForShowSupportButtons, }) =>
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
export const BlogPage = ({ content, posts, tags, services, getPosts, metaData, hasLikes = false, toggleLike, navigation, settings, pageCountForShowSupportButtons, isSignedInUser = false, onClickSignIn, }) => {
|
22
|
+
const _a = usePromptSignInProps(onClickSignIn), { requireSignIn } = _a, promptSignInProps = __rest(_a, ["requireSignIn"]);
|
23
|
+
const likes = useMemo(() => ({ toggleLike, hasLikes, isSignedInUser, requireSignIn }), [toggleLike, hasLikes, isSignedInUser, requireSignIn]);
|
24
|
+
return (React.createElement("main", null,
|
25
|
+
React.createElement(LikesContext.Provider, { value: likes },
|
26
|
+
React.createElement(FeedContext.Provider, { value: {
|
27
|
+
posts: posts.posts,
|
28
|
+
pinnedPost: posts.pinnedPost,
|
29
|
+
totalCount: posts.count,
|
30
|
+
tags,
|
31
|
+
services: services !== null && services !== void 0 ? services : [],
|
32
|
+
getPosts,
|
33
|
+
pageCountForShowSupportButtons,
|
34
|
+
} },
|
35
|
+
React.createElement(PageConstructorProvider, Object.assign({}, settings),
|
36
|
+
metaData ? React.createElement(MetaWrapper, Object.assign({}, metaData)) : null,
|
37
|
+
React.createElement(PageConstructor, { content: content, custom: componentMap, navigation: navigation })))),
|
38
|
+
React.createElement(PromptSignIn, Object.assign({}, promptSignInProps))));
|
39
|
+
};
|
@@ -3,5 +3,7 @@ import { ToggleLikeCallbackType } from '../models/common';
|
|
3
3
|
export interface LikesContextProps {
|
4
4
|
toggleLike?: ToggleLikeCallbackType;
|
5
5
|
hasLikes?: boolean;
|
6
|
+
isSignedInUser?: boolean;
|
7
|
+
requireSignIn?: React.MouseEventHandler;
|
6
8
|
}
|
7
9
|
export declare const LikesContext: React.Context<LikesContextProps>;
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/**
|
2
|
+
* Timer to automatically update `open` state after a given duration
|
3
|
+
* @param {number} openTimestamp - UNIX timestamp in milliseconds
|
4
|
+
* @param {number} openDuration - in milliseconds
|
5
|
+
* @returns {{open: boolean}} {open} - whether the state is open
|
6
|
+
*/
|
7
|
+
export declare function useOpenCloseTimer(openTimestamp?: number, openDuration?: number): {
|
8
|
+
open: boolean;
|
9
|
+
};
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import { useEffect, useState } from 'react';
|
2
|
+
/**
|
3
|
+
* Timer to automatically update `open` state after a given duration
|
4
|
+
* @param {number} openTimestamp - UNIX timestamp in milliseconds
|
5
|
+
* @param {number} openDuration - in milliseconds
|
6
|
+
* @returns {{open: boolean}} {open} - whether the state is open
|
7
|
+
*/
|
8
|
+
export function useOpenCloseTimer(openTimestamp = Date.now(), openDuration = 4000) {
|
9
|
+
const open = Date.now() - openTimestamp < openDuration;
|
10
|
+
const [, reset] = useState(0); // time to reset `open` state
|
11
|
+
useEffect(() => {
|
12
|
+
const closeTime = openTimestamp + openDuration;
|
13
|
+
const delay = closeTime - Date.now();
|
14
|
+
if (delay <= 0) {
|
15
|
+
return;
|
16
|
+
}
|
17
|
+
const timer = setTimeout(() => {
|
18
|
+
reset(Date.now);
|
19
|
+
}, delay);
|
20
|
+
// eslint-disable-next-line consistent-return
|
21
|
+
return () => {
|
22
|
+
clearTimeout(timer);
|
23
|
+
};
|
24
|
+
}, [openTimestamp, openDuration]);
|
25
|
+
return { open };
|
26
|
+
}
|
@@ -17,6 +17,8 @@ export declare enum Keyset {
|
|
17
17
|
Search = "search_placeholder",
|
18
18
|
AllTags = "label_all_tags",
|
19
19
|
ActionSavedOnly = "action_saved_only",
|
20
|
-
AllServices = "label_all_services"
|
20
|
+
AllServices = "label_all_services",
|
21
|
+
PromptSignInOnLike = "prompt_sign_in_on_like",
|
22
|
+
SignIn = "Sign In"
|
21
23
|
}
|
22
24
|
export declare const i18: (key: string, params?: import("@gravity-ui/i18n").Params | undefined) => string;
|
package/build/esm/i18n/index.js
CHANGED
@@ -21,6 +21,8 @@ export var Keyset;
|
|
21
21
|
Keyset["AllTags"] = "label_all_tags";
|
22
22
|
Keyset["ActionSavedOnly"] = "action_saved_only";
|
23
23
|
Keyset["AllServices"] = "label_all_services";
|
24
|
+
Keyset["PromptSignInOnLike"] = "prompt_sign_in_on_like";
|
25
|
+
Keyset["SignIn"] = "Sign In";
|
24
26
|
})(Keyset || (Keyset = {}));
|
25
27
|
i18n.registerKeyset(Lang.En, KEYSET_NAME, {
|
26
28
|
[Keyset.Title]: 'Blog',
|
@@ -39,11 +41,13 @@ i18n.registerKeyset(Lang.En, KEYSET_NAME, {
|
|
39
41
|
[Keyset.AllTags]: 'All topics',
|
40
42
|
[Keyset.ActionSavedOnly]: 'Saved',
|
41
43
|
[Keyset.AllServices]: 'All Services',
|
44
|
+
[Keyset.PromptSignInOnLike]: 'Please sign in to save your bookmarks',
|
42
45
|
[Keyset.ContextReadingTime]: [
|
43
46
|
'{{count}} min to read',
|
44
47
|
'{{count}} mins to read',
|
45
48
|
'{{count}} mins to read',
|
46
49
|
],
|
50
|
+
[Keyset.SignIn]: 'Sign In',
|
47
51
|
});
|
48
52
|
i18n.registerKeyset(Lang.Ru, KEYSET_NAME, {
|
49
53
|
[Keyset.Title]: 'Блог',
|
@@ -62,10 +66,12 @@ i18n.registerKeyset(Lang.Ru, KEYSET_NAME, {
|
|
62
66
|
[Keyset.AllTags]: 'Все темы',
|
63
67
|
[Keyset.ActionSavedOnly]: 'Сохранённые',
|
64
68
|
[Keyset.AllServices]: 'Все сервисы',
|
69
|
+
[Keyset.PromptSignInOnLike]: 'Войдите, чтобы добавить доклад в своё расписание',
|
65
70
|
[Keyset.ContextReadingTime]: [
|
66
71
|
'{{count}} минута чтения',
|
67
72
|
'{{count}} минуты чтения',
|
68
73
|
'{{count}} минут чтения',
|
69
74
|
],
|
75
|
+
[Keyset.SignIn]: 'Войти',
|
70
76
|
});
|
71
77
|
export const i18 = i18n.keyset(KEYSET_NAME);
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@gravity-ui/blog-constructor",
|
3
|
-
"version": "3.
|
3
|
+
"version": "3.5.0-alpha.0",
|
4
4
|
"description": "Gravity UI Blog Constructor",
|
5
5
|
"license": "MIT",
|
6
6
|
"repository": {
|
@@ -141,5 +141,8 @@
|
|
141
141
|
"*.{json,yaml,yml,md}": [
|
142
142
|
"prettier --write"
|
143
143
|
]
|
144
|
+
},
|
145
|
+
"publishConfig": {
|
146
|
+
"tag": "alpha"
|
144
147
|
}
|
145
148
|
}
|