@cloud-ru/uikit-product-modal-predefined 2.1.4 → 2.2.1
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/CHANGELOG.md +22 -0
- package/dist/cjs/helperComponents/NoteItem/NoteItem.d.ts +3 -1
- package/dist/cjs/helperComponents/NoteItem/NoteItem.js +19 -2
- package/dist/cjs/helperComponents/NoteItem/styles.module.css +34 -0
- package/dist/cjs/helperComponents/NoteItemMobile/NoteItemMobile.d.ts +1 -1
- package/dist/cjs/helperComponents/NoteItemMobile/NoteItemMobile.js +19 -2
- package/dist/cjs/helperComponents/NoteItemMobile/styles.module.css +39 -0
- package/dist/esm/helperComponents/NoteItem/NoteItem.d.ts +3 -1
- package/dist/esm/helperComponents/NoteItem/NoteItem.js +20 -3
- package/dist/esm/helperComponents/NoteItem/styles.module.css +34 -0
- package/dist/esm/helperComponents/NoteItemMobile/NoteItemMobile.d.ts +1 -1
- package/dist/esm/helperComponents/NoteItemMobile/NoteItemMobile.js +20 -3
- package/dist/esm/helperComponents/NoteItemMobile/styles.module.css +39 -0
- package/package.json +5 -5
- package/src/helperComponents/NoteItem/NoteItem.tsx +51 -2
- package/src/helperComponents/NoteItem/styles.module.scss +34 -0
- package/src/helperComponents/NoteItemMobile/NoteItemMobile.tsx +48 -2
- package/src/helperComponents/NoteItemMobile/styles.module.scss +38 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,28 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## 2.2.1 (2026-04-03)
|
|
7
|
+
|
|
8
|
+
### Only dependencies have been changed
|
|
9
|
+
* [@cloud-ru/uikit-product-copy-line@2.1.9]($PUBLIC_PROJECT_URL/blob/master/packages/copy-line/CHANGELOG.md)
|
|
10
|
+
* [@cloud-ru/uikit-product-icons@17.2.0]($PUBLIC_PROJECT_URL/blob/master/packages/icons/CHANGELOG.md)
|
|
11
|
+
* [@cloud-ru/uikit-product-mobile-modal@2.1.2]($PUBLIC_PROJECT_URL/blob/master/packages/mobile-modal/CHANGELOG.md)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# 2.2.0 (2026-03-31)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* **FF-7462:** add video into release modal ([0f9bedd](https://github.com/cloud-ru-tech/uikit-product/commit/0f9bedd7c9989b660131a24be5df70a75cb4ba25))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
6
28
|
## 2.1.4 (2026-03-31)
|
|
7
29
|
|
|
8
30
|
|
|
@@ -8,5 +8,7 @@ export type NoteItemProps = {
|
|
|
8
8
|
src: string;
|
|
9
9
|
alt: string;
|
|
10
10
|
};
|
|
11
|
+
/** URL видео (при наличии показывается вместо статичного изображения) */
|
|
12
|
+
video?: string;
|
|
11
13
|
};
|
|
12
|
-
export declare function NoteItem({ title, description, image }: NoteItemProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export declare function NoteItem({ title, description, image, video }: NoteItemProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -5,10 +5,27 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.NoteItem = NoteItem;
|
|
7
7
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_1 = require("react");
|
|
8
9
|
const uikit_product_markdown_1 = require("@cloud-ru/uikit-product-markdown");
|
|
9
10
|
const scroll_1 = require("@snack-uikit/scroll");
|
|
11
|
+
const skeleton_1 = require("@snack-uikit/skeleton");
|
|
10
12
|
const typography_1 = require("@snack-uikit/typography");
|
|
11
13
|
const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
|
|
12
|
-
function
|
|
13
|
-
|
|
14
|
+
function NoteItemMedia({ image, video }) {
|
|
15
|
+
const [videoReady, setVideoReady] = (0, react_1.useState)(false);
|
|
16
|
+
const [videoError, setVideoError] = (0, react_1.useState)(false);
|
|
17
|
+
(0, react_1.useEffect)(() => {
|
|
18
|
+
if (!video) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
setVideoReady(false);
|
|
22
|
+
setVideoError(false);
|
|
23
|
+
}, [video]);
|
|
24
|
+
if (!video) {
|
|
25
|
+
return (0, jsx_runtime_1.jsx)("img", { src: image.src, alt: image.alt, className: styles_module_scss_1.default.noteItemIllustration });
|
|
26
|
+
}
|
|
27
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.noteItemIllustrationSlot, children: videoError ? ((0, jsx_runtime_1.jsx)("img", { src: image.src, alt: image.alt, className: styles_module_scss_1.default.noteItemIllustration })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("video", { src: video, className: styles_module_scss_1.default.noteItemVideo, muted: true, loop: true, playsInline: true, autoPlay: true, onLoadedData: () => setVideoReady(true), onError: () => setVideoError(true), "aria-hidden": true }), !videoReady && ((0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.noteItemMediaSkeletonOverlay, children: (0, jsx_runtime_1.jsx)(skeleton_1.Skeleton, { width: 380, height: 380, borderRadius: 8, loading: true }) }))] })) }));
|
|
28
|
+
}
|
|
29
|
+
function NoteItem({ title, description, image, video }) {
|
|
30
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.noteItemWrapper, children: [(0, jsx_runtime_1.jsx)(scroll_1.Scroll, { size: 's', barHideStrategy: 'never', children: (0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.noteItemText, children: [(0, jsx_runtime_1.jsx)(typography_1.Typography.SansTitleL, { children: title }), (0, jsx_runtime_1.jsx)(uikit_product_markdown_1.Markdown, { value: description, className: styles_module_scss_1.default.noteItemMarkdownViewer })] }) }), (0, jsx_runtime_1.jsx)(NoteItemMedia, { image: image, video: video })] }));
|
|
14
31
|
}
|
|
@@ -12,6 +12,15 @@
|
|
|
12
12
|
gap:var(--dimension-2m, 16px);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
.noteItemIllustrationSlot{
|
|
16
|
+
position:relative;
|
|
17
|
+
flex-shrink:0;
|
|
18
|
+
width:380px;
|
|
19
|
+
height:380px;
|
|
20
|
+
border-radius:var(--dimension-1m, 8px);
|
|
21
|
+
overflow:hidden;
|
|
22
|
+
}
|
|
23
|
+
|
|
15
24
|
.noteItemIllustration{
|
|
16
25
|
border-radius:var(--dimension-1m, 8px);
|
|
17
26
|
width:380px;
|
|
@@ -19,6 +28,31 @@
|
|
|
19
28
|
-o-object-fit:cover;
|
|
20
29
|
object-fit:cover;
|
|
21
30
|
pointer-events:none;
|
|
31
|
+
display:block;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.noteItemIllustrationSlot .noteItemIllustration,
|
|
35
|
+
.noteItemVideo{
|
|
36
|
+
width:100%;
|
|
37
|
+
height:100%;
|
|
38
|
+
border-radius:0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.noteItemVideo{
|
|
42
|
+
-o-object-fit:cover;
|
|
43
|
+
object-fit:cover;
|
|
44
|
+
pointer-events:none;
|
|
45
|
+
display:block;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.noteItemMediaSkeletonOverlay{
|
|
49
|
+
position:absolute;
|
|
50
|
+
inset:0;
|
|
51
|
+
display:flex;
|
|
52
|
+
align-items:center;
|
|
53
|
+
justify-content:center;
|
|
54
|
+
border-radius:inherit;
|
|
55
|
+
pointer-events:none;
|
|
22
56
|
}
|
|
23
57
|
|
|
24
58
|
.noteItemMarkdownViewer{
|
|
@@ -5,5 +5,5 @@ type NoteItemMobileProps = NoteItemProps & {
|
|
|
5
5
|
childrenScrollRefs: RefObject<HTMLElement[]>;
|
|
6
6
|
onScrollRefInitialized(): void;
|
|
7
7
|
};
|
|
8
|
-
export declare function NoteItemMobile({ title, description, image, childrenScrollRefs, index, onScrollRefInitialized, }: NoteItemMobileProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export declare function NoteItemMobile({ title, description, image, video, childrenScrollRefs, index, onScrollRefInitialized, }: NoteItemMobileProps): import("react/jsx-runtime").JSX.Element;
|
|
9
9
|
export {};
|
|
@@ -5,15 +5,32 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.NoteItemMobile = NoteItemMobile;
|
|
7
7
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_1 = require("react");
|
|
8
9
|
const uikit_product_markdown_1 = require("@cloud-ru/uikit-product-markdown");
|
|
9
10
|
const scroll_1 = require("@snack-uikit/scroll");
|
|
11
|
+
const skeleton_1 = require("@snack-uikit/skeleton");
|
|
10
12
|
const typography_1 = require("@snack-uikit/typography");
|
|
11
13
|
const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
|
|
12
|
-
function
|
|
14
|
+
function NoteItemMobileMedia({ image, video }) {
|
|
15
|
+
const [videoReady, setVideoReady] = (0, react_1.useState)(false);
|
|
16
|
+
const [videoError, setVideoError] = (0, react_1.useState)(false);
|
|
17
|
+
(0, react_1.useEffect)(() => {
|
|
18
|
+
if (!video) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
setVideoReady(false);
|
|
22
|
+
setVideoError(false);
|
|
23
|
+
}, [video]);
|
|
24
|
+
if (!video) {
|
|
25
|
+
return (0, jsx_runtime_1.jsx)("img", { src: image.src, alt: image.alt, className: styles_module_scss_1.default.noteItemIllustration });
|
|
26
|
+
}
|
|
27
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.noteItemIllustrationSlot, children: videoError ? ((0, jsx_runtime_1.jsx)("img", { src: image.src, alt: image.alt, className: styles_module_scss_1.default.noteItemIllustration })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("video", { src: video, className: styles_module_scss_1.default.noteItemVideo, muted: true, loop: true, playsInline: true, autoPlay: true, onLoadedData: () => setVideoReady(true), onError: () => setVideoError(true), "aria-hidden": true }), !videoReady && ((0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.noteItemMediaSkeletonOverlay, children: (0, jsx_runtime_1.jsx)(skeleton_1.Skeleton, { width: '100%', height: '100%', borderRadius: 8 }) }))] })) }));
|
|
28
|
+
}
|
|
29
|
+
function NoteItemMobile({ title, description, image, video, childrenScrollRefs, index, onScrollRefInitialized, }) {
|
|
13
30
|
return ((0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.noteItemWrapper, children: (0, jsx_runtime_1.jsx)(scroll_1.Scroll, { size: 'm', barHideStrategy: 'never', ref: el => {
|
|
14
31
|
if (childrenScrollRefs.current && el) {
|
|
15
32
|
childrenScrollRefs.current[index] = el;
|
|
16
33
|
onScrollRefInitialized();
|
|
17
34
|
}
|
|
18
|
-
}, children: (0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.noteItemContent, children: [(0, jsx_runtime_1.jsx)(
|
|
35
|
+
}, children: (0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.noteItemContent, children: [(0, jsx_runtime_1.jsx)(NoteItemMobileMedia, { image: image, video: video }), (0, jsx_runtime_1.jsx)(typography_1.Typography.SansTitleL, { children: title }), (0, jsx_runtime_1.jsx)(uikit_product_markdown_1.Markdown, { value: description, className: styles_module_scss_1.default.noteItemMarkdownViewer })] }) }) }));
|
|
19
36
|
}
|
|
@@ -10,11 +10,50 @@
|
|
|
10
10
|
padding-right:var(--dimension-2m, 16px);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
.noteItemIllustrationSlot{
|
|
14
|
+
position:relative;
|
|
15
|
+
width:100%;
|
|
16
|
+
max-width:380px;
|
|
17
|
+
align-self:center;
|
|
18
|
+
aspect-ratio:1/1;
|
|
19
|
+
border-radius:var(--dimension-1m, 8px);
|
|
20
|
+
overflow:hidden;
|
|
21
|
+
}
|
|
22
|
+
|
|
13
23
|
.noteItemIllustration{
|
|
14
24
|
width:100%;
|
|
25
|
+
height:auto;
|
|
15
26
|
pointer-events:none;
|
|
16
27
|
max-width:380px;
|
|
17
28
|
align-self:center;
|
|
29
|
+
display:block;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.noteItemIllustrationSlot .noteItemIllustration{
|
|
33
|
+
width:100%;
|
|
34
|
+
height:100%;
|
|
35
|
+
max-width:none;
|
|
36
|
+
-o-object-fit:cover;
|
|
37
|
+
object-fit:cover;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.noteItemVideo{
|
|
41
|
+
width:100%;
|
|
42
|
+
height:100%;
|
|
43
|
+
-o-object-fit:cover;
|
|
44
|
+
object-fit:cover;
|
|
45
|
+
pointer-events:none;
|
|
46
|
+
display:block;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.noteItemMediaSkeletonOverlay{
|
|
50
|
+
position:absolute;
|
|
51
|
+
inset:0;
|
|
52
|
+
display:flex;
|
|
53
|
+
align-items:stretch;
|
|
54
|
+
justify-content:stretch;
|
|
55
|
+
border-radius:inherit;
|
|
56
|
+
pointer-events:none;
|
|
18
57
|
}
|
|
19
58
|
|
|
20
59
|
.noteItemSkeletonWrapper{
|
|
@@ -8,5 +8,7 @@ export type NoteItemProps = {
|
|
|
8
8
|
src: string;
|
|
9
9
|
alt: string;
|
|
10
10
|
};
|
|
11
|
+
/** URL видео (при наличии показывается вместо статичного изображения) */
|
|
12
|
+
video?: string;
|
|
11
13
|
};
|
|
12
|
-
export declare function NoteItem({ title, description, image }: NoteItemProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export declare function NoteItem({ title, description, image, video }: NoteItemProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,8 +1,25 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
2
3
|
import { Markdown } from '@cloud-ru/uikit-product-markdown';
|
|
3
4
|
import { Scroll } from '@snack-uikit/scroll';
|
|
5
|
+
import { Skeleton } from '@snack-uikit/skeleton';
|
|
4
6
|
import { Typography } from '@snack-uikit/typography';
|
|
5
7
|
import styles from './styles.module.css';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
function NoteItemMedia({ image, video }) {
|
|
9
|
+
const [videoReady, setVideoReady] = useState(false);
|
|
10
|
+
const [videoError, setVideoError] = useState(false);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (!video) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
setVideoReady(false);
|
|
16
|
+
setVideoError(false);
|
|
17
|
+
}, [video]);
|
|
18
|
+
if (!video) {
|
|
19
|
+
return _jsx("img", { src: image.src, alt: image.alt, className: styles.noteItemIllustration });
|
|
20
|
+
}
|
|
21
|
+
return (_jsx("div", { className: styles.noteItemIllustrationSlot, children: videoError ? (_jsx("img", { src: image.src, alt: image.alt, className: styles.noteItemIllustration })) : (_jsxs(_Fragment, { children: [_jsx("video", { src: video, className: styles.noteItemVideo, muted: true, loop: true, playsInline: true, autoPlay: true, onLoadedData: () => setVideoReady(true), onError: () => setVideoError(true), "aria-hidden": true }), !videoReady && (_jsx("div", { className: styles.noteItemMediaSkeletonOverlay, children: _jsx(Skeleton, { width: 380, height: 380, borderRadius: 8, loading: true }) }))] })) }));
|
|
22
|
+
}
|
|
23
|
+
export function NoteItem({ title, description, image, video }) {
|
|
24
|
+
return (_jsxs("div", { className: styles.noteItemWrapper, children: [_jsx(Scroll, { size: 's', barHideStrategy: 'never', children: _jsxs("div", { className: styles.noteItemText, children: [_jsx(Typography.SansTitleL, { children: title }), _jsx(Markdown, { value: description, className: styles.noteItemMarkdownViewer })] }) }), _jsx(NoteItemMedia, { image: image, video: video })] }));
|
|
8
25
|
}
|
|
@@ -12,6 +12,15 @@
|
|
|
12
12
|
gap:var(--dimension-2m, 16px);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
.noteItemIllustrationSlot{
|
|
16
|
+
position:relative;
|
|
17
|
+
flex-shrink:0;
|
|
18
|
+
width:380px;
|
|
19
|
+
height:380px;
|
|
20
|
+
border-radius:var(--dimension-1m, 8px);
|
|
21
|
+
overflow:hidden;
|
|
22
|
+
}
|
|
23
|
+
|
|
15
24
|
.noteItemIllustration{
|
|
16
25
|
border-radius:var(--dimension-1m, 8px);
|
|
17
26
|
width:380px;
|
|
@@ -19,6 +28,31 @@
|
|
|
19
28
|
-o-object-fit:cover;
|
|
20
29
|
object-fit:cover;
|
|
21
30
|
pointer-events:none;
|
|
31
|
+
display:block;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.noteItemIllustrationSlot .noteItemIllustration,
|
|
35
|
+
.noteItemVideo{
|
|
36
|
+
width:100%;
|
|
37
|
+
height:100%;
|
|
38
|
+
border-radius:0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.noteItemVideo{
|
|
42
|
+
-o-object-fit:cover;
|
|
43
|
+
object-fit:cover;
|
|
44
|
+
pointer-events:none;
|
|
45
|
+
display:block;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.noteItemMediaSkeletonOverlay{
|
|
49
|
+
position:absolute;
|
|
50
|
+
inset:0;
|
|
51
|
+
display:flex;
|
|
52
|
+
align-items:center;
|
|
53
|
+
justify-content:center;
|
|
54
|
+
border-radius:inherit;
|
|
55
|
+
pointer-events:none;
|
|
22
56
|
}
|
|
23
57
|
|
|
24
58
|
.noteItemMarkdownViewer{
|
|
@@ -5,5 +5,5 @@ type NoteItemMobileProps = NoteItemProps & {
|
|
|
5
5
|
childrenScrollRefs: RefObject<HTMLElement[]>;
|
|
6
6
|
onScrollRefInitialized(): void;
|
|
7
7
|
};
|
|
8
|
-
export declare function NoteItemMobile({ title, description, image, childrenScrollRefs, index, onScrollRefInitialized, }: NoteItemMobileProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export declare function NoteItemMobile({ title, description, image, video, childrenScrollRefs, index, onScrollRefInitialized, }: NoteItemMobileProps): import("react/jsx-runtime").JSX.Element;
|
|
9
9
|
export {};
|
|
@@ -1,13 +1,30 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
2
3
|
import { Markdown } from '@cloud-ru/uikit-product-markdown';
|
|
3
4
|
import { Scroll } from '@snack-uikit/scroll';
|
|
5
|
+
import { Skeleton } from '@snack-uikit/skeleton';
|
|
4
6
|
import { Typography } from '@snack-uikit/typography';
|
|
5
7
|
import styles from './styles.module.css';
|
|
6
|
-
|
|
8
|
+
function NoteItemMobileMedia({ image, video }) {
|
|
9
|
+
const [videoReady, setVideoReady] = useState(false);
|
|
10
|
+
const [videoError, setVideoError] = useState(false);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (!video) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
setVideoReady(false);
|
|
16
|
+
setVideoError(false);
|
|
17
|
+
}, [video]);
|
|
18
|
+
if (!video) {
|
|
19
|
+
return _jsx("img", { src: image.src, alt: image.alt, className: styles.noteItemIllustration });
|
|
20
|
+
}
|
|
21
|
+
return (_jsx("div", { className: styles.noteItemIllustrationSlot, children: videoError ? (_jsx("img", { src: image.src, alt: image.alt, className: styles.noteItemIllustration })) : (_jsxs(_Fragment, { children: [_jsx("video", { src: video, className: styles.noteItemVideo, muted: true, loop: true, playsInline: true, autoPlay: true, onLoadedData: () => setVideoReady(true), onError: () => setVideoError(true), "aria-hidden": true }), !videoReady && (_jsx("div", { className: styles.noteItemMediaSkeletonOverlay, children: _jsx(Skeleton, { width: '100%', height: '100%', borderRadius: 8 }) }))] })) }));
|
|
22
|
+
}
|
|
23
|
+
export function NoteItemMobile({ title, description, image, video, childrenScrollRefs, index, onScrollRefInitialized, }) {
|
|
7
24
|
return (_jsx("div", { className: styles.noteItemWrapper, children: _jsx(Scroll, { size: 'm', barHideStrategy: 'never', ref: el => {
|
|
8
25
|
if (childrenScrollRefs.current && el) {
|
|
9
26
|
childrenScrollRefs.current[index] = el;
|
|
10
27
|
onScrollRefInitialized();
|
|
11
28
|
}
|
|
12
|
-
}, children: _jsxs("div", { className: styles.noteItemContent, children: [_jsx(
|
|
29
|
+
}, children: _jsxs("div", { className: styles.noteItemContent, children: [_jsx(NoteItemMobileMedia, { image: image, video: video }), _jsx(Typography.SansTitleL, { children: title }), _jsx(Markdown, { value: description, className: styles.noteItemMarkdownViewer })] }) }) }));
|
|
13
30
|
}
|
|
@@ -10,11 +10,50 @@
|
|
|
10
10
|
padding-right:var(--dimension-2m, 16px);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
.noteItemIllustrationSlot{
|
|
14
|
+
position:relative;
|
|
15
|
+
width:100%;
|
|
16
|
+
max-width:380px;
|
|
17
|
+
align-self:center;
|
|
18
|
+
aspect-ratio:1/1;
|
|
19
|
+
border-radius:var(--dimension-1m, 8px);
|
|
20
|
+
overflow:hidden;
|
|
21
|
+
}
|
|
22
|
+
|
|
13
23
|
.noteItemIllustration{
|
|
14
24
|
width:100%;
|
|
25
|
+
height:auto;
|
|
15
26
|
pointer-events:none;
|
|
16
27
|
max-width:380px;
|
|
17
28
|
align-self:center;
|
|
29
|
+
display:block;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.noteItemIllustrationSlot .noteItemIllustration{
|
|
33
|
+
width:100%;
|
|
34
|
+
height:100%;
|
|
35
|
+
max-width:none;
|
|
36
|
+
-o-object-fit:cover;
|
|
37
|
+
object-fit:cover;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.noteItemVideo{
|
|
41
|
+
width:100%;
|
|
42
|
+
height:100%;
|
|
43
|
+
-o-object-fit:cover;
|
|
44
|
+
object-fit:cover;
|
|
45
|
+
pointer-events:none;
|
|
46
|
+
display:block;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.noteItemMediaSkeletonOverlay{
|
|
50
|
+
position:absolute;
|
|
51
|
+
inset:0;
|
|
52
|
+
display:flex;
|
|
53
|
+
align-items:stretch;
|
|
54
|
+
justify-content:stretch;
|
|
55
|
+
border-radius:inherit;
|
|
56
|
+
pointer-events:none;
|
|
18
57
|
}
|
|
19
58
|
|
|
20
59
|
.noteItemSkeletonWrapper{
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloud-ru/uikit-product-modal-predefined",
|
|
3
3
|
"title": "Modal Predefined",
|
|
4
|
-
"version": "2.1
|
|
4
|
+
"version": "2.2.1",
|
|
5
5
|
"sideEffects": [
|
|
6
6
|
"*.css",
|
|
7
7
|
"*.woff",
|
|
@@ -36,10 +36,10 @@
|
|
|
36
36
|
},
|
|
37
37
|
"scripts": {},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@cloud-ru/uikit-product-copy-line": "2.1.
|
|
40
|
-
"@cloud-ru/uikit-product-icons": "17.
|
|
39
|
+
"@cloud-ru/uikit-product-copy-line": "2.1.9",
|
|
40
|
+
"@cloud-ru/uikit-product-icons": "17.2.0",
|
|
41
41
|
"@cloud-ru/uikit-product-markdown": "1.1.4",
|
|
42
|
-
"@cloud-ru/uikit-product-mobile-modal": "2.1.
|
|
42
|
+
"@cloud-ru/uikit-product-mobile-modal": "2.1.2",
|
|
43
43
|
"@cloud-ru/uikit-product-switch-row": "1.1.5",
|
|
44
44
|
"@cloud-ru/uikit-product-toggles-predefined": "2.0.5",
|
|
45
45
|
"@cloud-ru/uikit-product-utils": "9.1.0",
|
|
@@ -57,5 +57,5 @@
|
|
|
57
57
|
"peerDependencies": {
|
|
58
58
|
"@cloud-ru/uikit-product-locale": "*"
|
|
59
59
|
},
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "7ab3fb759acc8f2f742b85ac3fefdc02540c58f6"
|
|
61
61
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
|
|
1
3
|
import { Markdown } from '@cloud-ru/uikit-product-markdown';
|
|
2
4
|
import { Scroll } from '@snack-uikit/scroll';
|
|
5
|
+
import { Skeleton } from '@snack-uikit/skeleton';
|
|
3
6
|
import { Typography } from '@snack-uikit/typography';
|
|
4
7
|
|
|
5
8
|
import styles from './styles.module.scss';
|
|
@@ -11,9 +14,55 @@ export type NoteItemProps = {
|
|
|
11
14
|
description: string;
|
|
12
15
|
/** Иллюстрация (изображение) */
|
|
13
16
|
image: { src: string; alt: string };
|
|
17
|
+
/** URL видео (при наличии показывается вместо статичного изображения) */
|
|
18
|
+
video?: string;
|
|
14
19
|
};
|
|
15
20
|
|
|
16
|
-
|
|
21
|
+
function NoteItemMedia({ image, video }: Pick<NoteItemProps, 'image' | 'video'>) {
|
|
22
|
+
const [videoReady, setVideoReady] = useState(false);
|
|
23
|
+
const [videoError, setVideoError] = useState(false);
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!video) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
setVideoReady(false);
|
|
30
|
+
setVideoError(false);
|
|
31
|
+
}, [video]);
|
|
32
|
+
|
|
33
|
+
if (!video) {
|
|
34
|
+
return <img src={image.src} alt={image.alt} className={styles.noteItemIllustration} />;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<div className={styles.noteItemIllustrationSlot}>
|
|
39
|
+
{videoError ? (
|
|
40
|
+
<img src={image.src} alt={image.alt} className={styles.noteItemIllustration} />
|
|
41
|
+
) : (
|
|
42
|
+
<>
|
|
43
|
+
<video
|
|
44
|
+
src={video}
|
|
45
|
+
className={styles.noteItemVideo}
|
|
46
|
+
muted
|
|
47
|
+
loop
|
|
48
|
+
playsInline
|
|
49
|
+
autoPlay
|
|
50
|
+
onLoadedData={() => setVideoReady(true)}
|
|
51
|
+
onError={() => setVideoError(true)}
|
|
52
|
+
aria-hidden
|
|
53
|
+
/>
|
|
54
|
+
{!videoReady && (
|
|
55
|
+
<div className={styles.noteItemMediaSkeletonOverlay}>
|
|
56
|
+
<Skeleton width={380} height={380} borderRadius={8} loading />
|
|
57
|
+
</div>
|
|
58
|
+
)}
|
|
59
|
+
</>
|
|
60
|
+
)}
|
|
61
|
+
</div>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function NoteItem({ title, description, image, video }: NoteItemProps) {
|
|
17
66
|
return (
|
|
18
67
|
<div className={styles.noteItemWrapper}>
|
|
19
68
|
<Scroll size='s' barHideStrategy='never'>
|
|
@@ -22,7 +71,7 @@ export function NoteItem({ title, description, image }: NoteItemProps) {
|
|
|
22
71
|
<Markdown value={description} className={styles.noteItemMarkdownViewer} />
|
|
23
72
|
</div>
|
|
24
73
|
</Scroll>
|
|
25
|
-
<
|
|
74
|
+
<NoteItemMedia image={image} video={video} />
|
|
26
75
|
</div>
|
|
27
76
|
);
|
|
28
77
|
}
|
|
@@ -14,12 +14,46 @@
|
|
|
14
14
|
gap: styles-theme-variables.$dimension-2m;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
.noteItemIllustrationSlot {
|
|
18
|
+
position: relative;
|
|
19
|
+
flex-shrink: 0;
|
|
20
|
+
width: 380px;
|
|
21
|
+
height: 380px;
|
|
22
|
+
border-radius: styles-theme-variables.$dimension-1m;
|
|
23
|
+
overflow: hidden;
|
|
24
|
+
}
|
|
25
|
+
|
|
17
26
|
.noteItemIllustration {
|
|
18
27
|
border-radius: styles-theme-variables.$dimension-1m;
|
|
19
28
|
width: 380px;
|
|
20
29
|
height: 380px;
|
|
21
30
|
object-fit: cover;
|
|
22
31
|
pointer-events: none;
|
|
32
|
+
display: block;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.noteItemIllustrationSlot .noteItemIllustration,
|
|
36
|
+
.noteItemVideo {
|
|
37
|
+
width: 100%;
|
|
38
|
+
height: 100%;
|
|
39
|
+
border-radius: 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.noteItemVideo {
|
|
43
|
+
object-fit: cover;
|
|
44
|
+
pointer-events: none;
|
|
45
|
+
display: block;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.noteItemMediaSkeletonOverlay {
|
|
49
|
+
position: absolute;
|
|
50
|
+
inset: 0;
|
|
51
|
+
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: center;
|
|
54
|
+
justify-content: center;
|
|
55
|
+
border-radius: inherit;
|
|
56
|
+
pointer-events: none;
|
|
23
57
|
}
|
|
24
58
|
|
|
25
59
|
.noteItemMarkdownViewer {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { RefObject } from 'react';
|
|
1
|
+
import { RefObject, useEffect, useState } from 'react';
|
|
2
2
|
|
|
3
3
|
import { Markdown } from '@cloud-ru/uikit-product-markdown';
|
|
4
4
|
import { Scroll } from '@snack-uikit/scroll';
|
|
5
|
+
import { Skeleton } from '@snack-uikit/skeleton';
|
|
5
6
|
import { Typography } from '@snack-uikit/typography';
|
|
6
7
|
|
|
7
8
|
import { NoteItemProps } from '../NoteItem';
|
|
@@ -13,10 +14,55 @@ type NoteItemMobileProps = NoteItemProps & {
|
|
|
13
14
|
onScrollRefInitialized(): void;
|
|
14
15
|
};
|
|
15
16
|
|
|
17
|
+
function NoteItemMobileMedia({ image, video }: Pick<NoteItemProps, 'image' | 'video'>) {
|
|
18
|
+
const [videoReady, setVideoReady] = useState(false);
|
|
19
|
+
const [videoError, setVideoError] = useState(false);
|
|
20
|
+
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (!video) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
setVideoReady(false);
|
|
26
|
+
setVideoError(false);
|
|
27
|
+
}, [video]);
|
|
28
|
+
|
|
29
|
+
if (!video) {
|
|
30
|
+
return <img src={image.src} alt={image.alt} className={styles.noteItemIllustration} />;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<div className={styles.noteItemIllustrationSlot}>
|
|
35
|
+
{videoError ? (
|
|
36
|
+
<img src={image.src} alt={image.alt} className={styles.noteItemIllustration} />
|
|
37
|
+
) : (
|
|
38
|
+
<>
|
|
39
|
+
<video
|
|
40
|
+
src={video}
|
|
41
|
+
className={styles.noteItemVideo}
|
|
42
|
+
muted
|
|
43
|
+
loop
|
|
44
|
+
playsInline
|
|
45
|
+
autoPlay
|
|
46
|
+
onLoadedData={() => setVideoReady(true)}
|
|
47
|
+
onError={() => setVideoError(true)}
|
|
48
|
+
aria-hidden
|
|
49
|
+
/>
|
|
50
|
+
{!videoReady && (
|
|
51
|
+
<div className={styles.noteItemMediaSkeletonOverlay}>
|
|
52
|
+
<Skeleton width='100%' height='100%' borderRadius={8} />
|
|
53
|
+
</div>
|
|
54
|
+
)}
|
|
55
|
+
</>
|
|
56
|
+
)}
|
|
57
|
+
</div>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
16
61
|
export function NoteItemMobile({
|
|
17
62
|
title,
|
|
18
63
|
description,
|
|
19
64
|
image,
|
|
65
|
+
video,
|
|
20
66
|
childrenScrollRefs,
|
|
21
67
|
index,
|
|
22
68
|
onScrollRefInitialized,
|
|
@@ -34,7 +80,7 @@ export function NoteItemMobile({
|
|
|
34
80
|
}}
|
|
35
81
|
>
|
|
36
82
|
<div className={styles.noteItemContent}>
|
|
37
|
-
<
|
|
83
|
+
<NoteItemMobileMedia image={image} video={video} />
|
|
38
84
|
<Typography.SansTitleL>{title}</Typography.SansTitleL>
|
|
39
85
|
<Markdown value={description} className={styles.noteItemMarkdownViewer} />
|
|
40
86
|
</div>
|
|
@@ -13,11 +13,49 @@
|
|
|
13
13
|
padding-right: styles-tokens-drawer.$dimension-2m;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
.noteItemIllustrationSlot {
|
|
17
|
+
position: relative;
|
|
18
|
+
width: 100%;
|
|
19
|
+
max-width: 380px;
|
|
20
|
+
align-self: center;
|
|
21
|
+
aspect-ratio: 1 / 1;
|
|
22
|
+
border-radius: styles-theme-variables.$dimension-1m;
|
|
23
|
+
overflow: hidden;
|
|
24
|
+
}
|
|
25
|
+
|
|
16
26
|
.noteItemIllustration {
|
|
17
27
|
width: 100%;
|
|
28
|
+
height: auto;
|
|
18
29
|
pointer-events: none;
|
|
19
30
|
max-width: 380px;
|
|
20
31
|
align-self: center;
|
|
32
|
+
display: block;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.noteItemIllustrationSlot .noteItemIllustration {
|
|
36
|
+
width: 100%;
|
|
37
|
+
height: 100%;
|
|
38
|
+
max-width: none;
|
|
39
|
+
object-fit: cover;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.noteItemVideo {
|
|
43
|
+
width: 100%;
|
|
44
|
+
height: 100%;
|
|
45
|
+
object-fit: cover;
|
|
46
|
+
pointer-events: none;
|
|
47
|
+
display: block;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.noteItemMediaSkeletonOverlay {
|
|
51
|
+
position: absolute;
|
|
52
|
+
inset: 0;
|
|
53
|
+
|
|
54
|
+
display: flex;
|
|
55
|
+
align-items: stretch;
|
|
56
|
+
justify-content: stretch;
|
|
57
|
+
border-radius: inherit;
|
|
58
|
+
pointer-events: none;
|
|
21
59
|
}
|
|
22
60
|
|
|
23
61
|
.noteItemSkeletonWrapper {
|