@cloud-ru/ds-uikit-product-modal-predefined 1.0.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/CHANGELOG.md +8 -0
- package/LICENSE +201 -0
- package/README.md +359 -0
- package/dist/cjs/components/DeleteModal/DeleteModal.d.ts +2 -0
- package/dist/cjs/components/DeleteModal/DeleteModal.js +39 -0
- package/dist/cjs/components/DeleteModal/index.d.ts +1 -0
- package/dist/cjs/components/DeleteModal/index.js +17 -0
- package/dist/cjs/components/DeleteModal/styles.module.css +33 -0
- package/dist/cjs/components/RecallModal/RecallModal.d.ts +2 -0
- package/dist/cjs/components/RecallModal/RecallModal.js +37 -0
- package/dist/cjs/components/RecallModal/index.d.ts +1 -0
- package/dist/cjs/components/RecallModal/index.js +17 -0
- package/dist/cjs/components/RecallModal/styles.module.css +33 -0
- package/dist/cjs/components/ReleaseNotes/ReleaseNotes.d.ts +7 -0
- package/dist/cjs/components/ReleaseNotes/ReleaseNotes.js +15 -0
- package/dist/cjs/components/ReleaseNotes/index.d.ts +1 -0
- package/dist/cjs/components/ReleaseNotes/index.js +17 -0
- package/dist/cjs/components/index.d.ts +3 -0
- package/dist/cjs/components/index.js +19 -0
- package/dist/cjs/constants.d.ts +27 -0
- package/dist/cjs/constants.js +30 -0
- package/dist/cjs/helperComponents/DesktopReleaseNotes/DesktopReleaseNotes.d.ts +2 -0
- package/dist/cjs/helperComponents/DesktopReleaseNotes/DesktopReleaseNotes.js +21 -0
- package/dist/cjs/helperComponents/DesktopReleaseNotes/index.d.ts +1 -0
- package/dist/cjs/helperComponents/DesktopReleaseNotes/index.js +17 -0
- package/dist/cjs/helperComponents/DesktopReleaseNotes/styles.module.css +19 -0
- package/dist/cjs/helperComponents/InputConfirm/InputConfirm.d.ts +48 -0
- package/dist/cjs/helperComponents/InputConfirm/InputConfirm.js +15 -0
- package/dist/cjs/helperComponents/InputConfirm/index.d.ts +1 -0
- package/dist/cjs/helperComponents/InputConfirm/index.js +17 -0
- package/dist/cjs/helperComponents/InputConfirm/styles.module.css +38 -0
- package/dist/cjs/helperComponents/MobileReleaseNotes/MobileReleaseNotes.d.ts +2 -0
- package/dist/cjs/helperComponents/MobileReleaseNotes/MobileReleaseNotes.js +26 -0
- package/dist/cjs/helperComponents/MobileReleaseNotes/index.d.ts +1 -0
- package/dist/cjs/helperComponents/MobileReleaseNotes/index.js +17 -0
- package/dist/cjs/helperComponents/NoteItem/NoteItem.d.ts +6 -0
- package/dist/cjs/helperComponents/NoteItem/NoteItem.js +20 -0
- package/dist/cjs/helperComponents/NoteItem/index.d.ts +1 -0
- package/dist/cjs/helperComponents/NoteItem/index.js +17 -0
- package/dist/cjs/helperComponents/NoteItem/styles.module.css +53 -0
- package/dist/cjs/helperComponents/ReleaseNotesContent/ReleaseNotesContent.d.ts +28 -0
- package/dist/cjs/helperComponents/ReleaseNotesContent/ReleaseNotesContent.js +30 -0
- package/dist/cjs/helperComponents/ReleaseNotesContent/index.d.ts +1 -0
- package/dist/cjs/helperComponents/ReleaseNotesContent/index.js +17 -0
- package/dist/cjs/helperComponents/ReleaseNotesContent/styles.module.css +40 -0
- package/dist/cjs/helperComponents/ReleaseNotesFooter/ReleaseNotesFooter.d.ts +25 -0
- package/dist/cjs/helperComponents/ReleaseNotesFooter/ReleaseNotesFooter.js +17 -0
- package/dist/cjs/helperComponents/ReleaseNotesFooter/index.d.ts +1 -0
- package/dist/cjs/helperComponents/ReleaseNotesFooter/index.js +17 -0
- package/dist/cjs/helperComponents/ReleaseNotesFooter/styles.module.css +27 -0
- package/dist/cjs/helperComponents/index.d.ts +6 -0
- package/dist/cjs/helperComponents/index.js +22 -0
- package/dist/cjs/hooks.d.ts +26 -0
- package/dist/cjs/hooks.js +59 -0
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.js +20 -0
- package/dist/cjs/locale/index.d.ts +143 -0
- package/dist/cjs/locale/index.js +76 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/style.css +243 -0
- package/dist/cjs/types.d.ts +67 -0
- package/dist/cjs/types.js +2 -0
- package/dist/esm/components/DeleteModal/DeleteModal.d.ts +2 -0
- package/dist/esm/components/DeleteModal/DeleteModal.js +33 -0
- package/dist/esm/components/DeleteModal/index.d.ts +1 -0
- package/dist/esm/components/DeleteModal/index.js +1 -0
- package/dist/esm/components/DeleteModal/styles.module.css +33 -0
- package/dist/esm/components/RecallModal/RecallModal.d.ts +2 -0
- package/dist/esm/components/RecallModal/RecallModal.js +31 -0
- package/dist/esm/components/RecallModal/index.d.ts +1 -0
- package/dist/esm/components/RecallModal/index.js +1 -0
- package/dist/esm/components/RecallModal/styles.module.css +33 -0
- package/dist/esm/components/ReleaseNotes/ReleaseNotes.d.ts +7 -0
- package/dist/esm/components/ReleaseNotes/ReleaseNotes.js +12 -0
- package/dist/esm/components/ReleaseNotes/index.d.ts +1 -0
- package/dist/esm/components/ReleaseNotes/index.js +1 -0
- package/dist/esm/components/index.d.ts +3 -0
- package/dist/esm/components/index.js +3 -0
- package/dist/esm/constants.d.ts +27 -0
- package/dist/esm/constants.js +27 -0
- package/dist/esm/helperComponents/DesktopReleaseNotes/DesktopReleaseNotes.d.ts +2 -0
- package/dist/esm/helperComponents/DesktopReleaseNotes/DesktopReleaseNotes.js +15 -0
- package/dist/esm/helperComponents/DesktopReleaseNotes/index.d.ts +1 -0
- package/dist/esm/helperComponents/DesktopReleaseNotes/index.js +1 -0
- package/dist/esm/helperComponents/DesktopReleaseNotes/styles.module.css +19 -0
- package/dist/esm/helperComponents/InputConfirm/InputConfirm.d.ts +48 -0
- package/dist/esm/helperComponents/InputConfirm/InputConfirm.js +9 -0
- package/dist/esm/helperComponents/InputConfirm/index.d.ts +1 -0
- package/dist/esm/helperComponents/InputConfirm/index.js +1 -0
- package/dist/esm/helperComponents/InputConfirm/styles.module.css +38 -0
- package/dist/esm/helperComponents/MobileReleaseNotes/MobileReleaseNotes.d.ts +2 -0
- package/dist/esm/helperComponents/MobileReleaseNotes/MobileReleaseNotes.js +23 -0
- package/dist/esm/helperComponents/MobileReleaseNotes/index.d.ts +1 -0
- package/dist/esm/helperComponents/MobileReleaseNotes/index.js +1 -0
- package/dist/esm/helperComponents/NoteItem/NoteItem.d.ts +6 -0
- package/dist/esm/helperComponents/NoteItem/NoteItem.js +14 -0
- package/dist/esm/helperComponents/NoteItem/index.d.ts +1 -0
- package/dist/esm/helperComponents/NoteItem/index.js +1 -0
- package/dist/esm/helperComponents/NoteItem/styles.module.css +53 -0
- package/dist/esm/helperComponents/ReleaseNotesContent/ReleaseNotesContent.d.ts +28 -0
- package/dist/esm/helperComponents/ReleaseNotesContent/ReleaseNotesContent.js +24 -0
- package/dist/esm/helperComponents/ReleaseNotesContent/index.d.ts +1 -0
- package/dist/esm/helperComponents/ReleaseNotesContent/index.js +1 -0
- package/dist/esm/helperComponents/ReleaseNotesContent/styles.module.css +40 -0
- package/dist/esm/helperComponents/ReleaseNotesFooter/ReleaseNotesFooter.d.ts +25 -0
- package/dist/esm/helperComponents/ReleaseNotesFooter/ReleaseNotesFooter.js +11 -0
- package/dist/esm/helperComponents/ReleaseNotesFooter/index.d.ts +1 -0
- package/dist/esm/helperComponents/ReleaseNotesFooter/index.js +1 -0
- package/dist/esm/helperComponents/ReleaseNotesFooter/styles.module.css +27 -0
- package/dist/esm/helperComponents/index.d.ts +6 -0
- package/dist/esm/helperComponents/index.js +6 -0
- package/dist/esm/hooks.d.ts +26 -0
- package/dist/esm/hooks.js +55 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/locale/index.d.ts +143 -0
- package/dist/esm/locale/index.js +73 -0
- package/dist/esm/style.css +243 -0
- package/dist/esm/types.d.ts +67 -0
- package/dist/esm/types.js +1 -0
- package/dist/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/tsconfig.esm.tsbuildinfo +1 -0
- package/package.json +63 -0
- package/src/components/DeleteModal/DeleteModal.tsx +116 -0
- package/src/components/DeleteModal/index.ts +1 -0
- package/src/components/DeleteModal/styles.module.scss +37 -0
- package/src/components/RecallModal/RecallModal.tsx +111 -0
- package/src/components/RecallModal/index.ts +1 -0
- package/src/components/RecallModal/styles.module.scss +37 -0
- package/src/components/ReleaseNotes/ReleaseNotes.tsx +15 -0
- package/src/components/ReleaseNotes/index.ts +1 -0
- package/src/components/index.ts +3 -0
- package/src/constants.ts +29 -0
- package/src/helperComponents/DesktopReleaseNotes/DesktopReleaseNotes.tsx +85 -0
- package/src/helperComponents/DesktopReleaseNotes/index.ts +1 -0
- package/src/helperComponents/DesktopReleaseNotes/styles.module.scss +24 -0
- package/src/helperComponents/InputConfirm/InputConfirm.tsx +72 -0
- package/src/helperComponents/InputConfirm/index.ts +1 -0
- package/src/helperComponents/InputConfirm/styles.module.scss +30 -0
- package/src/helperComponents/MobileReleaseNotes/MobileReleaseNotes.tsx +88 -0
- package/src/helperComponents/MobileReleaseNotes/index.ts +1 -0
- package/src/helperComponents/NoteItem/NoteItem.tsx +58 -0
- package/src/helperComponents/NoteItem/index.ts +1 -0
- package/src/helperComponents/NoteItem/styles.module.scss +54 -0
- package/src/helperComponents/ReleaseNotesContent/ReleaseNotesContent.tsx +119 -0
- package/src/helperComponents/ReleaseNotesContent/index.ts +1 -0
- package/src/helperComponents/ReleaseNotesContent/styles.module.scss +45 -0
- package/src/helperComponents/ReleaseNotesFooter/ReleaseNotesFooter.tsx +84 -0
- package/src/helperComponents/ReleaseNotesFooter/index.ts +1 -0
- package/src/helperComponents/ReleaseNotesFooter/styles.module.scss +25 -0
- package/src/helperComponents/index.ts +6 -0
- package/src/hooks.ts +89 -0
- package/src/index.ts +4 -0
- package/src/locale/index.ts +77 -0
- package/src/types.ts +80 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { FieldComboProps } from '@cloud-ru/ds-fields';
|
|
2
|
+
import { WithSupportProps } from '@cloud-ru/ds-utils';
|
|
3
|
+
export type InputConfirmProps = WithSupportProps<{
|
|
4
|
+
/** Текст, который нужно ввести для подтверждения */
|
|
5
|
+
confirmText: string;
|
|
6
|
+
/** Инструкция над текстом подтверждения */
|
|
7
|
+
confirmLabel?: string;
|
|
8
|
+
/** Скрыть кнопку копирования */
|
|
9
|
+
hideConfirmCopyButton?: boolean;
|
|
10
|
+
/** Значение поля */
|
|
11
|
+
value: string;
|
|
12
|
+
/** Текст ошибки */
|
|
13
|
+
error?: string;
|
|
14
|
+
/** Label поля */
|
|
15
|
+
label?: string;
|
|
16
|
+
/** Размер поля */
|
|
17
|
+
size?: FieldComboProps['size'];
|
|
18
|
+
/** Выравнивание copy-line */
|
|
19
|
+
copyLineAlign?: 'start' | 'space-between';
|
|
20
|
+
/** Placeholder поля */
|
|
21
|
+
placeholder: string;
|
|
22
|
+
/** Колбэк изменения значения */
|
|
23
|
+
onChange(value: string): void;
|
|
24
|
+
}>;
|
|
25
|
+
export declare const InputConfirm: import("react").ForwardRefExoticComponent<{
|
|
26
|
+
'data-test-id'?: string;
|
|
27
|
+
} & import("react").AriaAttributes & {
|
|
28
|
+
/** Текст, который нужно ввести для подтверждения */
|
|
29
|
+
confirmText: string;
|
|
30
|
+
/** Инструкция над текстом подтверждения */
|
|
31
|
+
confirmLabel?: string;
|
|
32
|
+
/** Скрыть кнопку копирования */
|
|
33
|
+
hideConfirmCopyButton?: boolean;
|
|
34
|
+
/** Значение поля */
|
|
35
|
+
value: string;
|
|
36
|
+
/** Текст ошибки */
|
|
37
|
+
error?: string;
|
|
38
|
+
/** Label поля */
|
|
39
|
+
label?: string;
|
|
40
|
+
/** Размер поля */
|
|
41
|
+
size?: FieldComboProps["size"];
|
|
42
|
+
/** Выравнивание copy-line */
|
|
43
|
+
copyLineAlign?: "start" | "space-between";
|
|
44
|
+
/** Placeholder поля */
|
|
45
|
+
placeholder: string;
|
|
46
|
+
/** Колбэк изменения значения */
|
|
47
|
+
onChange(value: string): void;
|
|
48
|
+
} & import("react").RefAttributes<HTMLInputElement>>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { FieldCombo, VALIDATION_STATE } from '@cloud-ru/ds-fields';
|
|
3
|
+
import { CopyButton } from '@cloud-ru/ds-uikit-product-copy';
|
|
4
|
+
import { forwardRef } from 'react';
|
|
5
|
+
import { TEST_IDS } from '../../constants.js';
|
|
6
|
+
import styles from './styles.module.css';
|
|
7
|
+
export const InputConfirm = forwardRef(function InputConfirm({ confirmText, confirmLabel, hideConfirmCopyButton, value, error, label, size = 'm', copyLineAlign = 'space-between', placeholder, onChange, ...rest }, ref) {
|
|
8
|
+
return (_jsxs("div", { className: styles.root, children: [confirmLabel && _jsx("span", { className: styles.confirmLabel, children: confirmLabel }), _jsxs("div", { className: styles.confirmText, "data-align": copyLineAlign, children: [_jsx("span", { className: styles.confirmValue, children: confirmText }), !hideConfirmCopyButton && _jsx(CopyButton, { valueToCopy: confirmText, "data-test-id": TEST_IDS.confirmCopyButton })] }), _jsx(FieldCombo, { ...rest, ref: ref, inputMode: 'text', label: label, required: Boolean(label), size: size, placeholder: placeholder, value: value, onChange: onChange, hint: error, validationState: error ? VALIDATION_STATE.Error : VALIDATION_STATE.Default, "data-test-id": TEST_IDS.confirmInput })] }));
|
|
9
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './InputConfirm.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './InputConfirm.js';
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
.root{
|
|
2
|
+
display:flex;
|
|
3
|
+
flex-direction:column;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.confirmText{
|
|
7
|
+
display:flex;
|
|
8
|
+
-moz-column-gap:var(--sn-primitive-dimension-8, 8px);
|
|
9
|
+
column-gap:var(--sn-primitive-dimension-8, 8px);
|
|
10
|
+
align-items:center;
|
|
11
|
+
justify-content:space-between;
|
|
12
|
+
margin-bottom:var(--sn-primitive-dimension-8, 8px);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.confirmText[data-align=start]{
|
|
16
|
+
-moz-column-gap:var(--sn-primitive-dimension-4, 4px);
|
|
17
|
+
column-gap:var(--sn-primitive-dimension-4, 4px);
|
|
18
|
+
justify-content:flex-start;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.confirmLabel{
|
|
22
|
+
font-family:var(--sn-regular-body-m-fontFamily, var(--sn-brand-font-fontFamily-regular-body, var(--sn-primitive-fontFamily-brandA-sans, SB Sans Interface)));
|
|
23
|
+
font-weight:var(--sn-regular-body-m-fontWeight, var(--sn-theme-typography-fontWeight-regular-body-m, var(--sn-brand-font-fontWeight-light-regular-body-m, var(--sn-primitive-font-fontWeightValue-400, 400))));
|
|
24
|
+
line-height:var(--sn-regular-body-m-lineHeight, var(--sn-density-typography-roleBody-lineHeightM, var(--sn-primitive-font-lineHeight-by16, 24px)));
|
|
25
|
+
font-size:var(--sn-regular-body-m-fontSize, var(--sn-density-typography-roleBody-fontSizeM, var(--sn-primitive-font-fontSize-16, 16px)));
|
|
26
|
+
letter-spacing:var(--sn-regular-body-m-letterSpacing, var(--sn-primitive-font-letterSpacing-m, 0.1px));
|
|
27
|
+
paragraph-spacing:var(--sn-regular-body-m-paragraphSpacing, var(--sn-primitive-font-paragraphSpacing-byFontSize14, 7px));
|
|
28
|
+
color:var(--sn-theme-color-available-version-textSecondary, var(--sn-brand-color-text-version-secondary, rgba(65, 66, 78, 0.8)));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.confirmValue{
|
|
32
|
+
font-family:var(--sn-regular-body-m-fontFamily, var(--sn-brand-font-fontFamily-regular-body, var(--sn-primitive-fontFamily-brandA-sans, SB Sans Interface)));
|
|
33
|
+
font-weight:var(--sn-regular-body-m-fontWeight, var(--sn-theme-typography-fontWeight-regular-body-m, var(--sn-brand-font-fontWeight-light-regular-body-m, var(--sn-primitive-font-fontWeightValue-400, 400))));
|
|
34
|
+
line-height:var(--sn-regular-body-m-lineHeight, var(--sn-density-typography-roleBody-lineHeightM, var(--sn-primitive-font-lineHeight-by16, 24px)));
|
|
35
|
+
font-size:var(--sn-regular-body-m-fontSize, var(--sn-density-typography-roleBody-fontSizeM, var(--sn-primitive-font-fontSize-16, 16px)));
|
|
36
|
+
letter-spacing:var(--sn-regular-body-m-letterSpacing, var(--sn-primitive-font-letterSpacing-m, 0.1px));
|
|
37
|
+
paragraph-spacing:var(--sn-regular-body-m-paragraphSpacing, var(--sn-primitive-font-paragraphSpacing-byFontSize14, 7px));
|
|
38
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { ReleaseNotesProps } from '../../types.js';
|
|
2
|
+
export declare function MobileReleaseNotes({ open, onClose, closeOnPopstate, contentState, items, loading, onReadLaterClick, onDataErrorRetryClick, onSlideChange, readLaterButtonProps, ...rest }: ReleaseNotesProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { BottomSheet } from '@cloud-ru/ds-bottom-sheet';
|
|
3
|
+
import { extractSupportProps } from '@cloud-ru/ds-utils';
|
|
4
|
+
import { CONTENT_STATE } from '../../constants.js';
|
|
5
|
+
import { useReleaseNotesNavigation } from '../../hooks.js';
|
|
6
|
+
import { modalPredefinedLocale } from '../../locale/index.js';
|
|
7
|
+
import { ReleaseNotesContent } from '../ReleaseNotesContent/index.js';
|
|
8
|
+
import { ReleaseNotesFooter } from '../ReleaseNotesFooter/index.js';
|
|
9
|
+
export function MobileReleaseNotes({ open, onClose, closeOnPopstate, contentState = CONTENT_STATE.Data, items, loading, onReadLaterClick, onDataErrorRetryClick, onSlideChange, readLaterButtonProps, ...rest }) {
|
|
10
|
+
const { t } = modalPredefinedLocale.useTranslations();
|
|
11
|
+
const { pageIndex, readablePageNumber, setPage, handleClose, handleReadLaterClick, handleNextPageClick, handlePrevPageClick, } = useReleaseNotesNavigation({ onClose, onReadLaterClick, onSlideChange });
|
|
12
|
+
const { onClick: onReadLaterButtonClick, ...readLaterButtonRest } = readLaterButtonProps ?? {};
|
|
13
|
+
const shouldShowFooter = contentState === CONTENT_STATE.Data && (loading || items.length > 0);
|
|
14
|
+
const handleReadLaterButtonClick = (event) => {
|
|
15
|
+
onReadLaterButtonClick?.(event);
|
|
16
|
+
handleReadLaterClick();
|
|
17
|
+
};
|
|
18
|
+
return (_jsx(BottomSheet
|
|
19
|
+
// Дефолт `withDividers` сменился на `true` — здесь вид сохраняем прежним.
|
|
20
|
+
, {
|
|
21
|
+
// Дефолт `withDividers` сменился на `true` — здесь вид сохраняем прежним.
|
|
22
|
+
withDividers: false, open: open, onClose: handleClose, closeOnPopstate: closeOnPopstate, title: t('releaseNotes.title'), content: _jsx(ReleaseNotesContent, { contentState: contentState, items: items, loading: loading, pageIndex: pageIndex, surface: 'bottomSheet', noDataTitle: t('releaseNotes.noDataTitle'), noDataDescription: t('releaseNotes.noDataDescription'), errorTitle: t('releaseNotes.errorTitle'), errorDescription: t('releaseNotes.errorDescription'), retryLabel: t('releaseNotes.retry'), onPageChange: setPage, onDataErrorRetryClick: onDataErrorRetryClick }), footer: shouldShowFooter ? (_jsx(ReleaseNotesFooter, { surface: 'bottomSheet', total: items.length, pageIndex: pageIndex, readablePageNumber: readablePageNumber, counterLabel: t('releaseNotes.counter', { page: readablePageNumber, total: items.length }), readLaterLabel: t('releaseNotes.readLater'), onReadLaterClick: handleReadLaterButtonClick, onPrevPageClick: handlePrevPageClick, onNextPageClick: () => handleNextPageClick(items.length), readLaterButtonProps: readLaterButtonRest })) : undefined, "data-content-state": contentState, "data-surface": 'bottomSheet', ...extractSupportProps(rest) }));
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './MobileReleaseNotes.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './MobileReleaseNotes.js';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { NoteItemProps } from '../../types.js';
|
|
2
|
+
type NoteItemComponentProps = NoteItemProps & {
|
|
3
|
+
surface?: 'modal' | 'bottomSheet';
|
|
4
|
+
};
|
|
5
|
+
export declare function NoteItem({ title, description, image, video, surface }: NoteItemComponentProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Markdown } from '@cloud-ru/ds-markdown';
|
|
3
|
+
import { BAR_HIDE_STRATEGY, Scroll } from '@cloud-ru/ds-scroll';
|
|
4
|
+
import { Skeleton } from '@cloud-ru/ds-skeleton';
|
|
5
|
+
import { Typography } from '@cloud-ru/ds-typography';
|
|
6
|
+
import { useState } from 'react';
|
|
7
|
+
import { TEST_IDS } from '../../constants.js';
|
|
8
|
+
import styles from './styles.module.css';
|
|
9
|
+
export function NoteItem({ title, description, image, video, surface = 'modal' }) {
|
|
10
|
+
const [isVideoReady, setIsVideoReady] = useState(false);
|
|
11
|
+
const [hasVideoError, setHasVideoError] = useState(false);
|
|
12
|
+
const shouldShowVideo = Boolean(video && !hasVideoError);
|
|
13
|
+
return (_jsxs("article", { className: styles.root, "data-surface": surface, "data-test-id": TEST_IDS.releaseNotesItem, children: [_jsxs("div", { className: styles.media, "data-test-id": TEST_IDS.releaseNotesMedia, children: [shouldShowVideo && (_jsxs(_Fragment, { children: [_jsx("video", { className: styles.video, src: video, muted: true, loop: true, playsInline: true, autoPlay: true, onLoadedData: () => setIsVideoReady(true), onError: () => setHasVideoError(true), "data-test-id": TEST_IDS.releaseNotesVideo }), !isVideoReady && (_jsx("div", { className: styles.videoSkeleton, "aria-hidden": true, children: _jsx(Skeleton, { loading: true, width: '100%', height: '100%' }) }))] })), !shouldShowVideo && _jsx("img", { className: styles.image, src: image.src, alt: image.alt })] }), _jsxs("div", { className: styles.content, children: [_jsx(Typography, { variant: 'headline', size: 's', children: title }), _jsx(Scroll, { className: styles.description, barHideStrategy: BAR_HIDE_STRATEGY.Leave, children: _jsx(Markdown, { value: description }) })] })] }));
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './NoteItem.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './NoteItem.js';
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
.root{
|
|
2
|
+
display:grid;
|
|
3
|
+
grid-template-columns:minmax(0, 1fr) minmax(0, 1fr);
|
|
4
|
+
-moz-column-gap:var(--sn-primitive-dimension-24, 24px);
|
|
5
|
+
column-gap:var(--sn-primitive-dimension-24, 24px);
|
|
6
|
+
min-height:calc(5 * var(--sn-primitive-dimension-64, 64px));
|
|
7
|
+
}
|
|
8
|
+
.root[data-surface=bottomSheet]{
|
|
9
|
+
grid-template-columns:minmax(0, 1fr);
|
|
10
|
+
row-gap:var(--sn-primitive-dimension-16, 16px);
|
|
11
|
+
min-height:0;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.media{
|
|
15
|
+
position:relative;
|
|
16
|
+
overflow:hidden;
|
|
17
|
+
min-width:0;
|
|
18
|
+
border-radius:var(--sn-primitive-dimension-16, 16px);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.image,
|
|
22
|
+
.video{
|
|
23
|
+
display:block;
|
|
24
|
+
width:100%;
|
|
25
|
+
height:100%;
|
|
26
|
+
-o-object-fit:cover;
|
|
27
|
+
object-fit:cover;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.videoSkeleton{
|
|
31
|
+
position:absolute;
|
|
32
|
+
inset:0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.content{
|
|
36
|
+
display:flex;
|
|
37
|
+
flex-direction:column;
|
|
38
|
+
row-gap:var(--sn-primitive-dimension-12, 12px);
|
|
39
|
+
min-width:0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.description{
|
|
43
|
+
min-height:0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.root[data-surface=modal] .content{
|
|
47
|
+
row-gap:var(--sn-primitive-dimension-16, 16px);
|
|
48
|
+
order:1;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.root[data-surface=modal] .media{
|
|
52
|
+
order:2;
|
|
53
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { NoteItemProps, ReleaseNotesContentState } from '../../types.js';
|
|
2
|
+
export type ReleaseNotesContentProps = {
|
|
3
|
+
/** Визуальное состояние */
|
|
4
|
+
contentState: ReleaseNotesContentState;
|
|
5
|
+
/** Новости */
|
|
6
|
+
items: NoteItemProps[];
|
|
7
|
+
/** Состояние загрузки */
|
|
8
|
+
loading?: boolean;
|
|
9
|
+
/** Текущая страница, zero-based */
|
|
10
|
+
pageIndex: number;
|
|
11
|
+
/** Поверхность */
|
|
12
|
+
surface: 'modal' | 'bottomSheet';
|
|
13
|
+
/** Заголовок no-data */
|
|
14
|
+
noDataTitle: string;
|
|
15
|
+
/** Описание no-data */
|
|
16
|
+
noDataDescription: string;
|
|
17
|
+
/** Заголовок ошибки */
|
|
18
|
+
errorTitle: string;
|
|
19
|
+
/** Описание ошибки */
|
|
20
|
+
errorDescription: string;
|
|
21
|
+
/** Label retry-кнопки */
|
|
22
|
+
retryLabel: string;
|
|
23
|
+
/** Смена страницы */
|
|
24
|
+
onPageChange(pageIndex: number): void;
|
|
25
|
+
/** Повторная загрузка */
|
|
26
|
+
onDataErrorRetryClick?(): void;
|
|
27
|
+
};
|
|
28
|
+
export declare function ReleaseNotesContent({ contentState, items, loading, pageIndex, surface, noDataTitle, noDataDescription, errorTitle, errorDescription, retryLabel, onPageChange, onDataErrorRetryClick, }: ReleaseNotesContentProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from '@cloud-ru/ds-button';
|
|
3
|
+
import { Carousel } from '@cloud-ru/ds-carousel';
|
|
4
|
+
import { CrossSVG } from '@cloud-ru/ds-icons/interface/system';
|
|
5
|
+
import { InfoBlock } from '@cloud-ru/ds-info-block';
|
|
6
|
+
import { Skeleton } from '@cloud-ru/ds-skeleton';
|
|
7
|
+
import cn from 'classnames';
|
|
8
|
+
import { CONTENT_STATE, TEST_IDS } from '../../constants.js';
|
|
9
|
+
import { NoteItem } from '../NoteItem/index.js';
|
|
10
|
+
import styles from './styles.module.css';
|
|
11
|
+
export function ReleaseNotesContent({ contentState, items, loading, pageIndex, surface, noDataTitle, noDataDescription, errorTitle, errorDescription, retryLabel, onPageChange, onDataErrorRetryClick, }) {
|
|
12
|
+
const total = items.length;
|
|
13
|
+
const hasItems = total > 0;
|
|
14
|
+
if (loading) {
|
|
15
|
+
return (_jsx("div", { className: styles.loading, "data-surface": surface, children: _jsx(Skeleton, { loading: true, width: '100%', height: '100%', borderRadius: 'var(--border-radius-l)' }) }));
|
|
16
|
+
}
|
|
17
|
+
if (contentState === CONTENT_STATE.Error) {
|
|
18
|
+
return (_jsx("div", { className: styles.stateWrapper, "data-surface": surface, children: _jsx(InfoBlock, { className: styles.state, size: 'l', title: errorTitle, content: errorDescription, icon: { icon: CrossSVG, appearance: 'neutral', background: true }, "data-test-id": TEST_IDS.releaseNotesError, footer: _jsx(Button, { view: 'filled', appearance: 'neutral', size: 'l', label: retryLabel, onClick: onDataErrorRetryClick, "data-test-id": TEST_IDS.releaseNotesRetryButton }) }) }));
|
|
19
|
+
}
|
|
20
|
+
if (contentState === CONTENT_STATE.NoData || !hasItems) {
|
|
21
|
+
return (_jsx("div", { className: styles.stateWrapper, "data-surface": surface, children: _jsx(InfoBlock, { className: styles.state, size: 'l', title: noDataTitle, content: noDataDescription, "data-test-id": TEST_IDS.releaseNotesNoData }) }));
|
|
22
|
+
}
|
|
23
|
+
return (_jsx("div", { className: cn(styles.root, styles[surface]), children: _jsx(Carousel, { arrows: false, pagination: false, swipe: true, state: { page: pageIndex, onChange: onPageChange }, className: styles.carousel, children: items.map(item => (_jsx(NoteItem, { ...item, surface: surface }, `${item.title}-${item.image.src}`))) }) }));
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ReleaseNotesContent.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ReleaseNotesContent.js';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
.root{
|
|
2
|
+
display:flex;
|
|
3
|
+
flex-direction:column;
|
|
4
|
+
row-gap:var(--sn-primitive-dimension-16, 16px);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.modal{
|
|
8
|
+
min-width:calc(11 * var(--sn-primitive-dimension-64, 64px));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.bottomSheet{
|
|
12
|
+
min-width:0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.carousel{
|
|
16
|
+
min-width:0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.stateWrapper{
|
|
20
|
+
display:flex;
|
|
21
|
+
flex-direction:column;
|
|
22
|
+
align-items:center;
|
|
23
|
+
justify-content:center;
|
|
24
|
+
width:100%;
|
|
25
|
+
}
|
|
26
|
+
.stateWrapper[data-surface=modal]{
|
|
27
|
+
height:calc(7 * var(--sn-primitive-dimension-64, 64px) - var(--sn-primitive-dimension-4, 4px));
|
|
28
|
+
}
|
|
29
|
+
.stateWrapper[data-surface=bottomSheet]{
|
|
30
|
+
min-height:calc(7 * var(--sn-primitive-dimension-64, 64px));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.state{
|
|
34
|
+
width:100%;
|
|
35
|
+
max-width:calc(9 * var(--sn-primitive-dimension-64, 64px) + 3 * var(--sn-primitive-dimension-16, 16px));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.loading{
|
|
39
|
+
height:calc(5 * var(--sn-primitive-dimension-64, 64px));
|
|
40
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ButtonProps } from '@cloud-ru/ds-button';
|
|
2
|
+
import { MouseEvent } from 'react';
|
|
3
|
+
export type ReleaseNotesFooterProps = {
|
|
4
|
+
/** Поверхность отображения */
|
|
5
|
+
surface: 'modal' | 'bottomSheet';
|
|
6
|
+
/** Количество страниц */
|
|
7
|
+
total: number;
|
|
8
|
+
/** Текущая страница, zero-based */
|
|
9
|
+
pageIndex: number;
|
|
10
|
+
/** Номер страницы для отображения */
|
|
11
|
+
readablePageNumber: number;
|
|
12
|
+
/** Текст счётчика «1 из N» (используется на bottomSheet) */
|
|
13
|
+
counterLabel: string;
|
|
14
|
+
/** Label кнопки «Ознакомиться позже» */
|
|
15
|
+
readLaterLabel: string;
|
|
16
|
+
/** Действие «Ознакомиться позже» */
|
|
17
|
+
onReadLaterClick(event: MouseEvent<HTMLButtonElement>): void;
|
|
18
|
+
/** Предыдущая страница */
|
|
19
|
+
onPrevPageClick(): void;
|
|
20
|
+
/** Следующая страница */
|
|
21
|
+
onNextPageClick(): void;
|
|
22
|
+
/** Дополнительные пропсы кнопки «Ознакомиться позже» */
|
|
23
|
+
readLaterButtonProps?: Partial<ButtonProps>;
|
|
24
|
+
};
|
|
25
|
+
export declare function ReleaseNotesFooter({ surface, total, pageIndex, readablePageNumber, counterLabel, readLaterLabel, onReadLaterClick, onPrevPageClick, onNextPageClick, readLaterButtonProps, }: ReleaseNotesFooterProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from '@cloud-ru/ds-button';
|
|
3
|
+
import { ChevronLeftSVG, ChevronRightSVG } from '@cloud-ru/ds-icons/interface/system';
|
|
4
|
+
import { TEST_IDS } from '../../constants.js';
|
|
5
|
+
import styles from './styles.module.css';
|
|
6
|
+
export function ReleaseNotesFooter({ surface, total, pageIndex, readablePageNumber, counterLabel, readLaterLabel, onReadLaterClick, onPrevPageClick, onNextPageClick, readLaterButtonProps, }) {
|
|
7
|
+
const hasPagination = total > 1;
|
|
8
|
+
const isModal = surface === 'modal';
|
|
9
|
+
const buttonSize = isModal ? 'm' : 'l';
|
|
10
|
+
return (_jsxs("div", { className: styles.root, "data-surface": surface, children: [_jsx(Button, { view: 'function', appearance: 'neutral', size: buttonSize, label: readLaterLabel, "data-test-id": TEST_IDS.releaseNotesReadLaterButton, ...readLaterButtonProps, onClick: onReadLaterClick }), hasPagination && (_jsxs("div", { className: styles.controls, children: [!isModal && _jsx("span", { className: styles.counter, children: counterLabel }), _jsx(Button, { view: 'outline', appearance: 'neutral', size: buttonSize, icon: _jsx(ChevronLeftSVG, {}), disabled: pageIndex === 0, onClick: onPrevPageClick, "data-test-id": TEST_IDS.releaseNotesPrevButton }), _jsx(Button, { view: 'outline', appearance: 'neutral', size: buttonSize, icon: _jsx(ChevronRightSVG, {}), disabled: readablePageNumber === total, onClick: onNextPageClick, "data-test-id": TEST_IDS.releaseNotesNextButton })] }))] }));
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ReleaseNotesFooter.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ReleaseNotesFooter.js';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
.root{
|
|
2
|
+
position:relative;
|
|
3
|
+
display:flex;
|
|
4
|
+
-moz-column-gap:var(--sn-primitive-dimension-16, 16px);
|
|
5
|
+
column-gap:var(--sn-primitive-dimension-16, 16px);
|
|
6
|
+
align-items:center;
|
|
7
|
+
justify-content:space-between;
|
|
8
|
+
width:100%;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.controls{
|
|
12
|
+
display:flex;
|
|
13
|
+
-moz-column-gap:var(--sn-primitive-dimension-8, 8px);
|
|
14
|
+
column-gap:var(--sn-primitive-dimension-8, 8px);
|
|
15
|
+
align-items:center;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.counter{
|
|
19
|
+
font-family:var(--sn-regular-body-m-fontFamily, var(--sn-brand-font-fontFamily-regular-body, var(--sn-primitive-fontFamily-brandA-sans, SB Sans Interface)));
|
|
20
|
+
font-weight:var(--sn-regular-body-m-fontWeight, var(--sn-theme-typography-fontWeight-regular-body-m, var(--sn-brand-font-fontWeight-light-regular-body-m, var(--sn-primitive-font-fontWeightValue-400, 400))));
|
|
21
|
+
line-height:var(--sn-regular-body-m-lineHeight, var(--sn-density-typography-roleBody-lineHeightM, var(--sn-primitive-font-lineHeight-by16, 24px)));
|
|
22
|
+
font-size:var(--sn-regular-body-m-fontSize, var(--sn-density-typography-roleBody-fontSizeM, var(--sn-primitive-font-fontSize-16, 16px)));
|
|
23
|
+
letter-spacing:var(--sn-regular-body-m-letterSpacing, var(--sn-primitive-font-letterSpacing-m, 0.1px));
|
|
24
|
+
paragraph-spacing:var(--sn-regular-body-m-paragraphSpacing, var(--sn-primitive-font-paragraphSpacing-byFontSize14, 7px));
|
|
25
|
+
color:var(--sn-theme-color-available-version-textTertiary, var(--sn-brand-color-text-version-tertiary, rgba(65, 66, 78, 0.5490196078)));
|
|
26
|
+
white-space:nowrap;
|
|
27
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * from './DesktopReleaseNotes/index.js';
|
|
2
|
+
export * from './InputConfirm/index.js';
|
|
3
|
+
export * from './MobileReleaseNotes/index.js';
|
|
4
|
+
export * from './NoteItem/index.js';
|
|
5
|
+
export * from './ReleaseNotesContent/index.js';
|
|
6
|
+
export * from './ReleaseNotesFooter/index.js';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * from './DesktopReleaseNotes/index.js';
|
|
2
|
+
export * from './InputConfirm/index.js';
|
|
3
|
+
export * from './MobileReleaseNotes/index.js';
|
|
4
|
+
export * from './NoteItem/index.js';
|
|
5
|
+
export * from './ReleaseNotesContent/index.js';
|
|
6
|
+
export * from './ReleaseNotesFooter/index.js';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
type TextFieldValidationParams = {
|
|
2
|
+
target?: string;
|
|
3
|
+
errorText: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function useTextFieldValidation({ target, errorText }: TextFieldValidationParams): {
|
|
6
|
+
value: string;
|
|
7
|
+
error: string;
|
|
8
|
+
handleChange: (nextValue: string) => void;
|
|
9
|
+
reset: () => void;
|
|
10
|
+
validate: () => boolean;
|
|
11
|
+
};
|
|
12
|
+
type ReleaseNotesNavigationParams = {
|
|
13
|
+
onClose(): void;
|
|
14
|
+
onReadLaterClick?(): void;
|
|
15
|
+
onSlideChange?(slide: number): void;
|
|
16
|
+
};
|
|
17
|
+
export declare function useReleaseNotesNavigation({ onClose, onReadLaterClick, onSlideChange }: ReleaseNotesNavigationParams): {
|
|
18
|
+
pageIndex: number;
|
|
19
|
+
readablePageNumber: number;
|
|
20
|
+
setPage: (nextPage: number) => void;
|
|
21
|
+
handleClose: () => void;
|
|
22
|
+
handleReadLaterClick: () => void;
|
|
23
|
+
handleNextPageClick: (totalPages: number) => void;
|
|
24
|
+
handlePrevPageClick: () => void;
|
|
25
|
+
};
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { useCallback, useState } from 'react';
|
|
2
|
+
export function useTextFieldValidation({ target, errorText }) {
|
|
3
|
+
const [value, setValue] = useState('');
|
|
4
|
+
const [error, setError] = useState('');
|
|
5
|
+
const handleChange = useCallback((nextValue) => {
|
|
6
|
+
setValue(nextValue);
|
|
7
|
+
if (target === nextValue) {
|
|
8
|
+
setError('');
|
|
9
|
+
}
|
|
10
|
+
}, [target]);
|
|
11
|
+
const reset = useCallback(() => {
|
|
12
|
+
setValue('');
|
|
13
|
+
setError('');
|
|
14
|
+
}, []);
|
|
15
|
+
const validate = useCallback(() => {
|
|
16
|
+
if (!target || target === value) {
|
|
17
|
+
setError('');
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
setError(errorText);
|
|
21
|
+
return false;
|
|
22
|
+
}, [errorText, target, value]);
|
|
23
|
+
return { value, error, handleChange, reset, validate };
|
|
24
|
+
}
|
|
25
|
+
export function useReleaseNotesNavigation({ onClose, onReadLaterClick, onSlideChange }) {
|
|
26
|
+
const [pageIndex, setPageIndex] = useState(0);
|
|
27
|
+
const setPage = useCallback((nextPage) => {
|
|
28
|
+
setPageIndex(nextPage);
|
|
29
|
+
onSlideChange?.(nextPage);
|
|
30
|
+
}, [onSlideChange]);
|
|
31
|
+
const handleClose = useCallback(() => {
|
|
32
|
+
setPageIndex(0);
|
|
33
|
+
onClose();
|
|
34
|
+
}, [onClose]);
|
|
35
|
+
const handleReadLaterClick = useCallback(() => {
|
|
36
|
+
setPageIndex(0);
|
|
37
|
+
onReadLaterClick?.();
|
|
38
|
+
onClose();
|
|
39
|
+
}, [onClose, onReadLaterClick]);
|
|
40
|
+
const handleNextPageClick = useCallback((totalPages) => {
|
|
41
|
+
setPage(Math.min(totalPages - 1, pageIndex + 1));
|
|
42
|
+
}, [pageIndex, setPage]);
|
|
43
|
+
const handlePrevPageClick = useCallback(() => {
|
|
44
|
+
setPage(Math.max(0, pageIndex - 1));
|
|
45
|
+
}, [pageIndex, setPage]);
|
|
46
|
+
return {
|
|
47
|
+
pageIndex,
|
|
48
|
+
readablePageNumber: pageIndex + 1,
|
|
49
|
+
setPage,
|
|
50
|
+
handleClose,
|
|
51
|
+
handleReadLaterClick,
|
|
52
|
+
handleNextPageClick,
|
|
53
|
+
handlePrevPageClick,
|
|
54
|
+
};
|
|
55
|
+
}
|