@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
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cloud-ru/ds-uikit-product-modal-predefined",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Product preset-компоненты для delete, recall и release notes сценариев на базе Modal и BottomSheet.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/cloud-ru-tech/snack-v2.git",
|
|
8
|
+
"directory": "packages/uikit-product-modal-predefined"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/cloud-ru-tech/snack-v2/tree/master/packages/uikit-product-modal-predefined",
|
|
11
|
+
"license": "Apache-2.0",
|
|
12
|
+
"author": "Robert Kuzhin <rikuzhin@cloud.ru>",
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "./dist/cjs/index.js",
|
|
15
|
+
"module": "./dist/esm/index.js",
|
|
16
|
+
"types": "./dist/esm/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"source": "./src/index.ts",
|
|
20
|
+
"types": "./dist/esm/index.d.ts",
|
|
21
|
+
"import": "./dist/esm/index.js",
|
|
22
|
+
"require": "./dist/cjs/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./locale": {
|
|
25
|
+
"source": "./src/locale/index.ts",
|
|
26
|
+
"types": "./dist/esm/locale/index.d.ts",
|
|
27
|
+
"import": "./dist/esm/locale/index.js",
|
|
28
|
+
"require": "./dist/cjs/locale/index.js"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"src",
|
|
34
|
+
"./CHANGELOG.md",
|
|
35
|
+
"./LICENSE"
|
|
36
|
+
],
|
|
37
|
+
"sideEffects": [
|
|
38
|
+
"*.css",
|
|
39
|
+
"**/*.css"
|
|
40
|
+
],
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"classnames": "^2.5.1",
|
|
43
|
+
"@cloud-ru/ds-adaptive": "^1.0.0",
|
|
44
|
+
"@cloud-ru/ds-button": "^1.0.0",
|
|
45
|
+
"@cloud-ru/ds-bottom-sheet": "^1.0.0",
|
|
46
|
+
"@cloud-ru/ds-carousel": "^1.0.0",
|
|
47
|
+
"@cloud-ru/ds-fields": "^1.0.0",
|
|
48
|
+
"@cloud-ru/ds-icons": "^1.0.0",
|
|
49
|
+
"@cloud-ru/ds-info-block": "^1.0.0",
|
|
50
|
+
"@cloud-ru/ds-locale": "^1.0.0",
|
|
51
|
+
"@cloud-ru/ds-markdown": "^1.0.0",
|
|
52
|
+
"@cloud-ru/ds-modal": "^1.0.0",
|
|
53
|
+
"@cloud-ru/ds-scroll": "^1.0.0",
|
|
54
|
+
"@cloud-ru/ds-skeleton": "^1.0.0",
|
|
55
|
+
"@cloud-ru/ds-tooltip": "^1.0.0",
|
|
56
|
+
"@cloud-ru/ds-typography": "^1.0.0",
|
|
57
|
+
"@cloud-ru/ds-utils": "^1.0.0",
|
|
58
|
+
"@cloud-ru/ds-uikit-product-copy": "^1.0.0"
|
|
59
|
+
},
|
|
60
|
+
"publishConfig": {
|
|
61
|
+
"access": "public"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { APPEARANCE, Button, VIEW } from '@cloud-ru/ds-button';
|
|
2
|
+
import { ModalCustom, WIDTH } from '@cloud-ru/ds-modal';
|
|
3
|
+
import { QuestionTooltip } from '@cloud-ru/ds-tooltip';
|
|
4
|
+
import { useRef } from 'react';
|
|
5
|
+
|
|
6
|
+
import { CONFIRM_TEXT_VARIANT, TEST_IDS } from '../../constants';
|
|
7
|
+
import { InputConfirm } from '../../helperComponents';
|
|
8
|
+
import { useTextFieldValidation } from '../../hooks';
|
|
9
|
+
import { modalPredefinedLocale } from '../../locale';
|
|
10
|
+
import { DeleteModalProps } from '../../types';
|
|
11
|
+
import styles from './styles.module.scss';
|
|
12
|
+
|
|
13
|
+
export function DeleteModal({
|
|
14
|
+
open,
|
|
15
|
+
onClose,
|
|
16
|
+
mode,
|
|
17
|
+
closeOnPopstate,
|
|
18
|
+
objectType,
|
|
19
|
+
titleTooltip,
|
|
20
|
+
onDelete,
|
|
21
|
+
deleting,
|
|
22
|
+
content,
|
|
23
|
+
confirmable = false,
|
|
24
|
+
confirmText,
|
|
25
|
+
hideConfirmCopyButton,
|
|
26
|
+
subtitle,
|
|
27
|
+
confirmTextVariant = CONFIRM_TEXT_VARIANT.Name,
|
|
28
|
+
...rest
|
|
29
|
+
}: DeleteModalProps) {
|
|
30
|
+
const { t } = modalPredefinedLocale.useTranslations();
|
|
31
|
+
const inputRef = useRef<HTMLInputElement>(null);
|
|
32
|
+
const { value, error, handleChange, reset, validate } = useTextFieldValidation({
|
|
33
|
+
target: confirmable ? confirmText : undefined,
|
|
34
|
+
errorText: t('confirm.error'),
|
|
35
|
+
});
|
|
36
|
+
const shouldShowConfirm = Boolean(confirmable && confirmText);
|
|
37
|
+
const title = objectType ? t('deleteModal.title', { objectType }) : t('deleteModal.fallbackTitle');
|
|
38
|
+
const confirmPlaceholder =
|
|
39
|
+
confirmTextVariant === CONFIRM_TEXT_VARIANT.Text ? t('confirm.textPlaceholder') : t('confirm.namePlaceholder');
|
|
40
|
+
|
|
41
|
+
const handleClose = () => {
|
|
42
|
+
reset();
|
|
43
|
+
onClose();
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const handleApproveClick = () => {
|
|
47
|
+
if (!validate()) {
|
|
48
|
+
inputRef.current?.focus();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
onDelete(handleClose);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<ModalCustom
|
|
57
|
+
open={open}
|
|
58
|
+
onClose={handleClose}
|
|
59
|
+
mode={mode}
|
|
60
|
+
closeOnPopstate={closeOnPopstate}
|
|
61
|
+
width={WIDTH.S}
|
|
62
|
+
data-test-id={TEST_IDS.deleteModal}
|
|
63
|
+
data-confirmable={confirmable || undefined}
|
|
64
|
+
{...rest}
|
|
65
|
+
>
|
|
66
|
+
<div className={styles.safeAreaTop} />
|
|
67
|
+
<ModalCustom.Header
|
|
68
|
+
title={title}
|
|
69
|
+
subtitle={subtitle}
|
|
70
|
+
slotAfterTitle={titleTooltip ? <QuestionTooltip size='s' tip={titleTooltip} /> : undefined}
|
|
71
|
+
/>
|
|
72
|
+
<ModalCustom.Body
|
|
73
|
+
className={styles.body}
|
|
74
|
+
content={
|
|
75
|
+
<div className={styles.content}>
|
|
76
|
+
{content ?? t('deleteModal.content')}
|
|
77
|
+
{shouldShowConfirm && (
|
|
78
|
+
<InputConfirm
|
|
79
|
+
ref={inputRef}
|
|
80
|
+
confirmText={confirmText ?? ''}
|
|
81
|
+
hideConfirmCopyButton={hideConfirmCopyButton}
|
|
82
|
+
value={value}
|
|
83
|
+
error={error}
|
|
84
|
+
size='l'
|
|
85
|
+
copyLineAlign='start'
|
|
86
|
+
confirmLabel={t('deleteModal.confirmLabel')}
|
|
87
|
+
placeholder={confirmPlaceholder}
|
|
88
|
+
onChange={handleChange}
|
|
89
|
+
/>
|
|
90
|
+
)}
|
|
91
|
+
</div>
|
|
92
|
+
}
|
|
93
|
+
/>
|
|
94
|
+
<div className={styles.safeAreaBottom} />
|
|
95
|
+
<ModalCustom.Footer>
|
|
96
|
+
<div className={styles.footer}>
|
|
97
|
+
<Button
|
|
98
|
+
view={VIEW.Outline}
|
|
99
|
+
appearance={APPEARANCE.Neutral}
|
|
100
|
+
label={t('deleteModal.cancel')}
|
|
101
|
+
onClick={handleClose}
|
|
102
|
+
data-test-id={TEST_IDS.cancelButton}
|
|
103
|
+
/>
|
|
104
|
+
<Button
|
|
105
|
+
view={VIEW.Filled}
|
|
106
|
+
appearance={APPEARANCE.Critical}
|
|
107
|
+
label={t('deleteModal.approve')}
|
|
108
|
+
loading={deleting}
|
|
109
|
+
onClick={handleApproveClick}
|
|
110
|
+
data-test-id={TEST_IDS.approveButton}
|
|
111
|
+
/>
|
|
112
|
+
</div>
|
|
113
|
+
</ModalCustom.Footer>
|
|
114
|
+
</ModalCustom>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DeleteModal';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
@use '@cloud-ru/ds-figma-variables/build/scss/styles/styles.module' as base;
|
|
2
|
+
@use '@cloud-ru/ds-figma-variables/build/scss/components/modal.module' as modal;
|
|
3
|
+
|
|
4
|
+
.safeAreaTop {
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
align-items: flex-start;
|
|
8
|
+
align-self: stretch;
|
|
9
|
+
|
|
10
|
+
padding-top: base.simple-var(modal.$modal, 'anatomy', 'container', 'safeArea', 'padding-top');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.safeAreaBottom {
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
align-items: flex-start;
|
|
17
|
+
align-self: stretch;
|
|
18
|
+
|
|
19
|
+
padding-bottom: base.simple-var(modal.$modal, 'anatomy', 'container', 'safeArea', 'padding-bottom');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.body {
|
|
23
|
+
min-height: auto;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.content {
|
|
27
|
+
display: flex;
|
|
28
|
+
flex-direction: column;
|
|
29
|
+
row-gap: base.$sn-primitive-dimension-16;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.footer {
|
|
33
|
+
display: flex;
|
|
34
|
+
column-gap: base.$sn-primitive-dimension-8;
|
|
35
|
+
justify-content: flex-end;
|
|
36
|
+
width: 100%;
|
|
37
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { APPEARANCE, Button, VIEW } from '@cloud-ru/ds-button';
|
|
2
|
+
import { ModalCustom, WIDTH } from '@cloud-ru/ds-modal';
|
|
3
|
+
import { QuestionTooltip } from '@cloud-ru/ds-tooltip';
|
|
4
|
+
import { useRef } from 'react';
|
|
5
|
+
|
|
6
|
+
import { TEST_IDS } from '../../constants';
|
|
7
|
+
import { InputConfirm } from '../../helperComponents';
|
|
8
|
+
import { useTextFieldValidation } from '../../hooks';
|
|
9
|
+
import { modalPredefinedLocale } from '../../locale';
|
|
10
|
+
import { RecallModalProps } from '../../types';
|
|
11
|
+
import styles from './styles.module.scss';
|
|
12
|
+
|
|
13
|
+
export function RecallModal({
|
|
14
|
+
open,
|
|
15
|
+
onClose,
|
|
16
|
+
mode,
|
|
17
|
+
closeOnPopstate,
|
|
18
|
+
titleTooltip,
|
|
19
|
+
onRecall,
|
|
20
|
+
loading,
|
|
21
|
+
content,
|
|
22
|
+
confirmable = false,
|
|
23
|
+
confirmText,
|
|
24
|
+
hideConfirmCopyButton,
|
|
25
|
+
subtitle,
|
|
26
|
+
...rest
|
|
27
|
+
}: RecallModalProps) {
|
|
28
|
+
const { t } = modalPredefinedLocale.useTranslations();
|
|
29
|
+
const inputRef = useRef<HTMLInputElement>(null);
|
|
30
|
+
const { value, error, handleChange, reset, validate } = useTextFieldValidation({
|
|
31
|
+
target: confirmable ? confirmText : undefined,
|
|
32
|
+
errorText: t('confirm.error'),
|
|
33
|
+
});
|
|
34
|
+
const shouldShowConfirm = Boolean(confirmable && confirmText);
|
|
35
|
+
|
|
36
|
+
const handleClose = () => {
|
|
37
|
+
reset();
|
|
38
|
+
onClose();
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const handleApproveClick = () => {
|
|
42
|
+
if (!validate()) {
|
|
43
|
+
inputRef.current?.focus();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
onRecall(handleClose);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<ModalCustom
|
|
52
|
+
open={open}
|
|
53
|
+
onClose={handleClose}
|
|
54
|
+
mode={mode}
|
|
55
|
+
closeOnPopstate={closeOnPopstate}
|
|
56
|
+
width={WIDTH.S}
|
|
57
|
+
data-test-id={TEST_IDS.recallModal}
|
|
58
|
+
data-confirmable={confirmable || undefined}
|
|
59
|
+
{...rest}
|
|
60
|
+
>
|
|
61
|
+
<div className={styles.safeAreaTop} />
|
|
62
|
+
<ModalCustom.Header
|
|
63
|
+
title={t('recallModal.title')}
|
|
64
|
+
subtitle={subtitle}
|
|
65
|
+
slotAfterTitle={titleTooltip ? <QuestionTooltip size='s' tip={titleTooltip} /> : undefined}
|
|
66
|
+
/>
|
|
67
|
+
<ModalCustom.Body
|
|
68
|
+
className={styles.body}
|
|
69
|
+
content={
|
|
70
|
+
<div className={styles.content}>
|
|
71
|
+
{content ?? t('recallModal.content')}
|
|
72
|
+
{shouldShowConfirm && (
|
|
73
|
+
<InputConfirm
|
|
74
|
+
ref={inputRef}
|
|
75
|
+
confirmText={confirmText ?? ''}
|
|
76
|
+
confirmLabel={t('recallModal.confirmLabel')}
|
|
77
|
+
hideConfirmCopyButton={hideConfirmCopyButton}
|
|
78
|
+
value={value}
|
|
79
|
+
error={error}
|
|
80
|
+
size='l'
|
|
81
|
+
copyLineAlign='start'
|
|
82
|
+
placeholder={t('confirm.namePlaceholder')}
|
|
83
|
+
onChange={handleChange}
|
|
84
|
+
/>
|
|
85
|
+
)}
|
|
86
|
+
</div>
|
|
87
|
+
}
|
|
88
|
+
/>
|
|
89
|
+
<div className={styles.safeAreaBottom} />
|
|
90
|
+
<ModalCustom.Footer>
|
|
91
|
+
<div className={styles.footer}>
|
|
92
|
+
<Button
|
|
93
|
+
view={VIEW.Outline}
|
|
94
|
+
appearance={APPEARANCE.Neutral}
|
|
95
|
+
label={t('recallModal.cancel')}
|
|
96
|
+
onClick={handleClose}
|
|
97
|
+
data-test-id={TEST_IDS.cancelButton}
|
|
98
|
+
/>
|
|
99
|
+
<Button
|
|
100
|
+
view={VIEW.Filled}
|
|
101
|
+
appearance={APPEARANCE.Critical}
|
|
102
|
+
label={t('recallModal.approve')}
|
|
103
|
+
loading={loading}
|
|
104
|
+
onClick={handleApproveClick}
|
|
105
|
+
data-test-id={TEST_IDS.approveButton}
|
|
106
|
+
/>
|
|
107
|
+
</div>
|
|
108
|
+
</ModalCustom.Footer>
|
|
109
|
+
</ModalCustom>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './RecallModal';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
@use '@cloud-ru/ds-figma-variables/build/scss/styles/styles.module' as base;
|
|
2
|
+
@use '@cloud-ru/ds-figma-variables/build/scss/components/modal.module' as modal;
|
|
3
|
+
|
|
4
|
+
.safeAreaTop {
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
align-items: flex-start;
|
|
8
|
+
align-self: stretch;
|
|
9
|
+
|
|
10
|
+
padding-top: base.simple-var(modal.$modal, 'anatomy', 'container', 'safeArea', 'padding-top');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.safeAreaBottom {
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
align-items: flex-start;
|
|
17
|
+
align-self: stretch;
|
|
18
|
+
|
|
19
|
+
padding-bottom: base.simple-var(modal.$modal, 'anatomy', 'container', 'safeArea', 'padding-bottom');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.body {
|
|
23
|
+
min-height: auto;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.content {
|
|
27
|
+
display: flex;
|
|
28
|
+
flex-direction: column;
|
|
29
|
+
row-gap: base.$sn-primitive-dimension-16;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.footer {
|
|
33
|
+
display: flex;
|
|
34
|
+
column-gap: base.$sn-primitive-dimension-8;
|
|
35
|
+
justify-content: flex-end;
|
|
36
|
+
width: 100%;
|
|
37
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { isMobileLayout, useAdaptiveLayout } from '@cloud-ru/ds-adaptive';
|
|
2
|
+
|
|
3
|
+
import { DesktopReleaseNotes, MobileReleaseNotes } from '../../helperComponents';
|
|
4
|
+
import { ReleaseNotesProps } from '../../types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Адаптивный release-notes: на `mobile` — bottom sheet, иначе — модальное окно. Поверхность выбирается
|
|
8
|
+
* по `useAdaptiveLayout()` из `@cloud-ru/ds-adaptive` и пропом не задаётся. Форс раскладки — через
|
|
9
|
+
* `withLayoutType(ReleaseNotes, 'mobile')` либо `AdaptiveProvider` в поддереве.
|
|
10
|
+
*/
|
|
11
|
+
export function ReleaseNotes(props: ReleaseNotesProps) {
|
|
12
|
+
const { layoutType } = useAdaptiveLayout();
|
|
13
|
+
|
|
14
|
+
return isMobileLayout(layoutType) ? <MobileReleaseNotes {...props} /> : <DesktopReleaseNotes {...props} />;
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ReleaseNotes';
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const CONTENT_STATE = {
|
|
2
|
+
Data: 'data',
|
|
3
|
+
NoData: 'noData',
|
|
4
|
+
Error: 'error',
|
|
5
|
+
} as const;
|
|
6
|
+
|
|
7
|
+
export const CONFIRM_TEXT_VARIANT = {
|
|
8
|
+
Name: 'name',
|
|
9
|
+
Text: 'text',
|
|
10
|
+
} as const;
|
|
11
|
+
|
|
12
|
+
export const TEST_IDS = {
|
|
13
|
+
deleteModal: 'delete-modal',
|
|
14
|
+
recallModal: 'recall-modal',
|
|
15
|
+
releaseNotes: 'release-notes',
|
|
16
|
+
approveButton: 'modal-predefined__approve-button',
|
|
17
|
+
cancelButton: 'modal-predefined__cancel-button',
|
|
18
|
+
confirmInput: 'modal-predefined__confirm-input',
|
|
19
|
+
confirmCopyButton: 'modal-predefined__confirm-copy-button',
|
|
20
|
+
releaseNotesItem: 'modal-predefined__release-notes-item',
|
|
21
|
+
releaseNotesMedia: 'modal-predefined__release-notes-media',
|
|
22
|
+
releaseNotesVideo: 'modal-predefined__release-notes-video',
|
|
23
|
+
releaseNotesError: 'modal-predefined__release-notes-error',
|
|
24
|
+
releaseNotesNoData: 'modal-predefined__release-notes-no-data',
|
|
25
|
+
releaseNotesRetryButton: 'modal-predefined__release-notes-retry-button',
|
|
26
|
+
releaseNotesReadLaterButton: 'modal-predefined__release-notes-read-later-button',
|
|
27
|
+
releaseNotesPrevButton: 'modal-predefined__release-notes-prev-button',
|
|
28
|
+
releaseNotesNextButton: 'modal-predefined__release-notes-next-button',
|
|
29
|
+
} as const;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { ModalCustom, WIDTH } from '@cloud-ru/ds-modal';
|
|
2
|
+
import { extractSupportProps } from '@cloud-ru/ds-utils';
|
|
3
|
+
|
|
4
|
+
import { CONTENT_STATE } from '../../constants';
|
|
5
|
+
import { useReleaseNotesNavigation } from '../../hooks';
|
|
6
|
+
import { modalPredefinedLocale } from '../../locale';
|
|
7
|
+
import { ReleaseNotesProps } from '../../types';
|
|
8
|
+
import { ReleaseNotesContent } from '../ReleaseNotesContent';
|
|
9
|
+
import { ReleaseNotesFooter } from '../ReleaseNotesFooter';
|
|
10
|
+
import styles from './styles.module.scss';
|
|
11
|
+
|
|
12
|
+
export function DesktopReleaseNotes({
|
|
13
|
+
open,
|
|
14
|
+
onClose,
|
|
15
|
+
closeOnPopstate,
|
|
16
|
+
contentState = CONTENT_STATE.Data,
|
|
17
|
+
items,
|
|
18
|
+
loading,
|
|
19
|
+
onReadLaterClick,
|
|
20
|
+
onDataErrorRetryClick,
|
|
21
|
+
onSlideChange,
|
|
22
|
+
...rest
|
|
23
|
+
}: ReleaseNotesProps) {
|
|
24
|
+
const { t } = modalPredefinedLocale.useTranslations();
|
|
25
|
+
const {
|
|
26
|
+
pageIndex,
|
|
27
|
+
readablePageNumber,
|
|
28
|
+
setPage,
|
|
29
|
+
handleClose,
|
|
30
|
+
handleReadLaterClick,
|
|
31
|
+
handleNextPageClick,
|
|
32
|
+
handlePrevPageClick,
|
|
33
|
+
} = useReleaseNotesNavigation({ onClose, onReadLaterClick, onSlideChange });
|
|
34
|
+
const shouldShowFooter = contentState === CONTENT_STATE.Data && (loading || items.length > 0);
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<ModalCustom
|
|
38
|
+
open={open}
|
|
39
|
+
onClose={handleClose}
|
|
40
|
+
closeOnPopstate={closeOnPopstate}
|
|
41
|
+
width={WIDTH.M}
|
|
42
|
+
data-content-state={contentState}
|
|
43
|
+
data-surface='modal'
|
|
44
|
+
{...extractSupportProps(rest)}
|
|
45
|
+
>
|
|
46
|
+
<div className={styles.safeAreaTop} />
|
|
47
|
+
<ModalCustom.Header title={t('releaseNotes.title')} />
|
|
48
|
+
<ModalCustom.Body
|
|
49
|
+
className={styles.body}
|
|
50
|
+
content={
|
|
51
|
+
<ReleaseNotesContent
|
|
52
|
+
contentState={contentState}
|
|
53
|
+
items={items}
|
|
54
|
+
loading={loading}
|
|
55
|
+
pageIndex={pageIndex}
|
|
56
|
+
surface='modal'
|
|
57
|
+
noDataTitle={t('releaseNotes.noDataTitle')}
|
|
58
|
+
noDataDescription={t('releaseNotes.noDataDescription')}
|
|
59
|
+
errorTitle={t('releaseNotes.errorTitle')}
|
|
60
|
+
errorDescription={t('releaseNotes.errorDescription')}
|
|
61
|
+
retryLabel={t('releaseNotes.retry')}
|
|
62
|
+
onPageChange={setPage}
|
|
63
|
+
onDataErrorRetryClick={onDataErrorRetryClick}
|
|
64
|
+
/>
|
|
65
|
+
}
|
|
66
|
+
/>
|
|
67
|
+
<div className={styles.safeAreaBottom} />
|
|
68
|
+
{shouldShowFooter && (
|
|
69
|
+
<ModalCustom.Footer>
|
|
70
|
+
<ReleaseNotesFooter
|
|
71
|
+
surface='modal'
|
|
72
|
+
total={items.length}
|
|
73
|
+
pageIndex={pageIndex}
|
|
74
|
+
readablePageNumber={readablePageNumber}
|
|
75
|
+
counterLabel={t('releaseNotes.counter', { page: readablePageNumber, total: items.length })}
|
|
76
|
+
readLaterLabel={t('releaseNotes.readLater')}
|
|
77
|
+
onReadLaterClick={handleReadLaterClick}
|
|
78
|
+
onPrevPageClick={handlePrevPageClick}
|
|
79
|
+
onNextPageClick={() => handleNextPageClick(items.length)}
|
|
80
|
+
/>
|
|
81
|
+
</ModalCustom.Footer>
|
|
82
|
+
)}
|
|
83
|
+
</ModalCustom>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DesktopReleaseNotes';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
@use '@cloud-ru/ds-figma-variables/build/scss/styles/styles.module' as base;
|
|
2
|
+
@use '@cloud-ru/ds-figma-variables/build/scss/components/modal.module' as modal;
|
|
3
|
+
|
|
4
|
+
.safeAreaTop {
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
align-items: flex-start;
|
|
8
|
+
align-self: stretch;
|
|
9
|
+
|
|
10
|
+
padding-top: base.simple-var(modal.$modal, 'anatomy', 'container', 'safeArea', 'padding-top');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.safeAreaBottom {
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
align-items: flex-start;
|
|
17
|
+
align-self: stretch;
|
|
18
|
+
|
|
19
|
+
padding-bottom: base.simple-var(modal.$modal, 'anatomy', 'container', 'safeArea', 'padding-bottom');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.body {
|
|
23
|
+
min-height: calc(6 * #{base.$sn-primitive-dimension-64});
|
|
24
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { FieldCombo, FieldComboProps, VALIDATION_STATE } from '@cloud-ru/ds-fields';
|
|
2
|
+
import { CopyButton } from '@cloud-ru/ds-uikit-product-copy';
|
|
3
|
+
import { WithSupportProps } from '@cloud-ru/ds-utils';
|
|
4
|
+
import { forwardRef } from 'react';
|
|
5
|
+
|
|
6
|
+
import { TEST_IDS } from '../../constants';
|
|
7
|
+
import styles from './styles.module.scss';
|
|
8
|
+
|
|
9
|
+
export type InputConfirmProps = WithSupportProps<{
|
|
10
|
+
/** Текст, который нужно ввести для подтверждения */
|
|
11
|
+
confirmText: string;
|
|
12
|
+
/** Инструкция над текстом подтверждения */
|
|
13
|
+
confirmLabel?: string;
|
|
14
|
+
/** Скрыть кнопку копирования */
|
|
15
|
+
hideConfirmCopyButton?: boolean;
|
|
16
|
+
/** Значение поля */
|
|
17
|
+
value: string;
|
|
18
|
+
/** Текст ошибки */
|
|
19
|
+
error?: string;
|
|
20
|
+
/** Label поля */
|
|
21
|
+
label?: string;
|
|
22
|
+
/** Размер поля */
|
|
23
|
+
size?: FieldComboProps['size'];
|
|
24
|
+
/** Выравнивание copy-line */
|
|
25
|
+
copyLineAlign?: 'start' | 'space-between';
|
|
26
|
+
/** Placeholder поля */
|
|
27
|
+
placeholder: string;
|
|
28
|
+
/** Колбэк изменения значения */
|
|
29
|
+
onChange(value: string): void;
|
|
30
|
+
}>;
|
|
31
|
+
|
|
32
|
+
export const InputConfirm = forwardRef<HTMLInputElement, InputConfirmProps>(function InputConfirm(
|
|
33
|
+
{
|
|
34
|
+
confirmText,
|
|
35
|
+
confirmLabel,
|
|
36
|
+
hideConfirmCopyButton,
|
|
37
|
+
value,
|
|
38
|
+
error,
|
|
39
|
+
label,
|
|
40
|
+
size = 'm',
|
|
41
|
+
copyLineAlign = 'space-between',
|
|
42
|
+
placeholder,
|
|
43
|
+
onChange,
|
|
44
|
+
...rest
|
|
45
|
+
},
|
|
46
|
+
ref,
|
|
47
|
+
) {
|
|
48
|
+
return (
|
|
49
|
+
<div className={styles.root}>
|
|
50
|
+
{confirmLabel && <span className={styles.confirmLabel}>{confirmLabel}</span>}
|
|
51
|
+
<div className={styles.confirmText} data-align={copyLineAlign}>
|
|
52
|
+
<span className={styles.confirmValue}>{confirmText}</span>
|
|
53
|
+
{!hideConfirmCopyButton && <CopyButton valueToCopy={confirmText} data-test-id={TEST_IDS.confirmCopyButton} />}
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<FieldCombo
|
|
57
|
+
{...rest}
|
|
58
|
+
ref={ref}
|
|
59
|
+
inputMode='text'
|
|
60
|
+
label={label}
|
|
61
|
+
required={Boolean(label)}
|
|
62
|
+
size={size}
|
|
63
|
+
placeholder={placeholder}
|
|
64
|
+
value={value}
|
|
65
|
+
onChange={onChange}
|
|
66
|
+
hint={error}
|
|
67
|
+
validationState={error ? VALIDATION_STATE.Error : VALIDATION_STATE.Default}
|
|
68
|
+
data-test-id={TEST_IDS.confirmInput}
|
|
69
|
+
/>
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './InputConfirm';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
@use '@cloud-ru/ds-figma-variables/build/scss/styles/styles.module' as base;
|
|
2
|
+
|
|
3
|
+
.root {
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.confirmText {
|
|
9
|
+
display: flex;
|
|
10
|
+
column-gap: base.$sn-primitive-dimension-8;
|
|
11
|
+
align-items: center;
|
|
12
|
+
justify-content: space-between;
|
|
13
|
+
|
|
14
|
+
margin-bottom: base.$sn-primitive-dimension-8;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.confirmText[data-align='start'] {
|
|
18
|
+
column-gap: base.$sn-primitive-dimension-4;
|
|
19
|
+
justify-content: flex-start;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.confirmLabel {
|
|
23
|
+
@include base.composite-var(base.$base-styles, 'sn', 'regular', 'body', 'm');
|
|
24
|
+
|
|
25
|
+
color: base.$sn-theme-color-available-version-textSecondary;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.confirmValue {
|
|
29
|
+
@include base.composite-var(base.$base-styles, 'sn', 'regular', 'body', 'm');
|
|
30
|
+
}
|