@salutejs/plasma-new-hope 0.193.0 → 0.194.0-canary.1558.11852073996.0
Sign up to get free protection for your applications and to get access to all the features.
- package/cjs/components/Modal/Modal.css +6 -0
- package/cjs/components/Modal/Modal.js +27 -13
- package/cjs/components/Modal/Modal.js.map +1 -1
- package/cjs/components/Modal/Modal.styles.js +27 -0
- package/cjs/components/Modal/Modal.styles.js.map +1 -0
- package/cjs/components/Modal/Modal.styles_tqsxxy.css +3 -0
- package/cjs/components/Modal/Modal.tokens.js +7 -1
- package/cjs/components/Modal/Modal.tokens.js.map +1 -1
- package/cjs/index.css +4 -0
- package/emotion/cjs/components/Modal/Modal.js +26 -12
- package/emotion/cjs/components/Modal/Modal.styles.js +27 -0
- package/emotion/cjs/components/Modal/Modal.template-doc.mdx +47 -0
- package/emotion/cjs/components/Modal/Modal.tokens.js +7 -1
- package/emotion/cjs/examples/plasma_b2c/components/Modal/Modal.config.js +1 -1
- package/emotion/cjs/examples/plasma_b2c/components/Modal/Modal.stories.tsx +90 -1
- package/emotion/cjs/examples/plasma_web/components/Modal/Modal.config.js +1 -1
- package/emotion/cjs/examples/plasma_web/components/Modal/Modal.stories.tsx +90 -1
- package/emotion/es/components/Modal/Modal.js +26 -12
- package/emotion/es/components/Modal/Modal.styles.js +20 -0
- package/emotion/es/components/Modal/Modal.template-doc.mdx +47 -0
- package/emotion/es/components/Modal/Modal.tokens.js +7 -1
- package/emotion/es/examples/plasma_b2c/components/Modal/Modal.config.js +1 -1
- package/emotion/es/examples/plasma_b2c/components/Modal/Modal.stories.tsx +90 -1
- package/emotion/es/examples/plasma_web/components/Modal/Modal.config.js +1 -1
- package/emotion/es/examples/plasma_web/components/Modal/Modal.stories.tsx +90 -1
- package/es/components/Modal/Modal.css +6 -0
- package/es/components/Modal/Modal.js +27 -13
- package/es/components/Modal/Modal.js.map +1 -1
- package/es/components/Modal/Modal.styles.js +21 -0
- package/es/components/Modal/Modal.styles.js.map +1 -0
- package/es/components/Modal/Modal.styles_tqsxxy.css +3 -0
- package/es/components/Modal/Modal.tokens.js +7 -1
- package/es/components/Modal/Modal.tokens.js.map +1 -1
- package/es/index.css +4 -0
- package/package.json +2 -2
- package/styled-components/cjs/components/Modal/Modal.js +26 -12
- package/styled-components/cjs/components/Modal/Modal.styles.js +24 -0
- package/styled-components/cjs/components/Modal/Modal.template-doc.mdx +47 -0
- package/styled-components/cjs/components/Modal/Modal.tokens.js +7 -1
- package/styled-components/cjs/examples/plasma_b2c/components/Modal/Modal.config.js +1 -1
- package/styled-components/cjs/examples/plasma_b2c/components/Modal/Modal.stories.tsx +90 -1
- package/styled-components/cjs/examples/plasma_web/components/Modal/Modal.config.js +1 -1
- package/styled-components/cjs/examples/plasma_web/components/Modal/Modal.stories.tsx +90 -1
- package/styled-components/es/components/Modal/Modal.js +26 -12
- package/styled-components/es/components/Modal/Modal.styles.js +17 -0
- package/styled-components/es/components/Modal/Modal.template-doc.mdx +47 -0
- package/styled-components/es/components/Modal/Modal.tokens.js +7 -1
- package/styled-components/es/examples/plasma_b2c/components/Modal/Modal.config.js +1 -1
- package/styled-components/es/examples/plasma_b2c/components/Modal/Modal.stories.tsx +90 -1
- package/styled-components/es/examples/plasma_web/components/Modal/Modal.config.js +1 -1
- package/styled-components/es/examples/plasma_web/components/Modal/Modal.stories.tsx +90 -1
- package/types/components/Modal/Modal.d.ts.map +1 -1
- package/types/components/Modal/Modal.styles.d.ts +5 -0
- package/types/components/Modal/Modal.styles.d.ts.map +1 -0
- package/types/components/Modal/Modal.tokens.d.ts +6 -0
- package/types/components/Modal/Modal.tokens.d.ts.map +1 -1
- package/types/components/Modal/Modal.types.d.ts +21 -1
- package/types/components/Modal/Modal.types.d.ts.map +1 -1
- package/types/components/Modal/index.d.ts +1 -1
- package/types/components/Modal/index.d.ts.map +1 -1
- package/types/examples/plasma_b2c/components/Modal/Modal.config.d.ts.map +1 -1
- package/types/examples/plasma_b2c/components/Modal/Modal.d.ts +7 -1
- package/types/examples/plasma_b2c/components/Modal/Modal.d.ts.map +1 -1
- package/types/examples/plasma_web/components/Modal/Modal.config.d.ts.map +1 -1
- package/types/examples/plasma_web/components/Modal/Modal.d.ts +7 -1
- package/types/examples/plasma_web/components/Modal/Modal.d.ts.map +1 -1
@@ -3,6 +3,7 @@ import styled from 'styled-components';
|
|
3
3
|
import type { ComponentProps } from 'react';
|
4
4
|
import type { StoryObj, Meta } from '@storybook/react';
|
5
5
|
import { SSRProvider } from '@salutejs/plasma-core';
|
6
|
+
import { disableProps } from '@salutejs/plasma-sb-utils';
|
6
7
|
|
7
8
|
import { PopupProvider, popupClasses } from '../Popup/Popup';
|
8
9
|
import { Button } from '../Button/Button';
|
@@ -18,6 +19,7 @@ export default {
|
|
18
19
|
docs: { story: { inline: false, iframeHeight: '30rem' } },
|
19
20
|
},
|
20
21
|
argTypes: {
|
22
|
+
...disableProps(['hasBody']),
|
21
23
|
placement: {
|
22
24
|
options: [
|
23
25
|
'center',
|
@@ -75,6 +77,7 @@ type StoryModalProps = ComponentProps<typeof Modal> & {
|
|
75
77
|
closeOnEsc: boolean;
|
76
78
|
closeOnOverlayClick: boolean;
|
77
79
|
withBlur: boolean;
|
80
|
+
hasClose?: boolean;
|
78
81
|
};
|
79
82
|
|
80
83
|
const StyledButton = styled(Button)`
|
@@ -135,6 +138,72 @@ const StoryModalDemo = ({ placement, offsetX, offsetY, ...rest }: StoryModalProp
|
|
135
138
|
const [isOpenB, setIsOpenB] = useState(false);
|
136
139
|
const [isOpenC, setIsOpenC] = useState(false);
|
137
140
|
|
141
|
+
return (
|
142
|
+
<SSRProvider>
|
143
|
+
<StyledWrapper>
|
144
|
+
<PopupProvider>
|
145
|
+
<ButtonWrapper>
|
146
|
+
<StyledButton text="Открыть A" onClick={() => setIsOpenA(true)} />
|
147
|
+
</ButtonWrapper>
|
148
|
+
<StyledModal
|
149
|
+
id="modalA"
|
150
|
+
frame="theme-root"
|
151
|
+
withAnimation
|
152
|
+
onClose={() => setIsOpenA(false)}
|
153
|
+
opened={isOpenA}
|
154
|
+
placement={placement}
|
155
|
+
offset={[offsetX, offsetY]}
|
156
|
+
hasBody
|
157
|
+
{...rest}
|
158
|
+
>
|
159
|
+
<Button onClick={() => setIsOpenA(false)}>Close</Button>
|
160
|
+
<ButtonWrapper>
|
161
|
+
<StyledButton text="Открыть B" onClick={() => setIsOpenB(true)} />
|
162
|
+
</ButtonWrapper>
|
163
|
+
<Modal
|
164
|
+
id="modalB"
|
165
|
+
frame="theme-root"
|
166
|
+
onClose={() => setIsOpenB(false)}
|
167
|
+
opened={isOpenB}
|
168
|
+
placement="left"
|
169
|
+
offset={[offsetX, offsetY]}
|
170
|
+
hasBody
|
171
|
+
{...rest}
|
172
|
+
>
|
173
|
+
<Button style={{ marginRight: '1rem' }} onClick={() => setIsOpenB(false)}>
|
174
|
+
Close
|
175
|
+
</Button>
|
176
|
+
<ButtonWrapper>
|
177
|
+
<StyledButton text="Открыть C" onClick={() => setIsOpenC(true)} />
|
178
|
+
</ButtonWrapper>
|
179
|
+
<Modal
|
180
|
+
id="modalC"
|
181
|
+
frame="theme-root"
|
182
|
+
onClose={() => setIsOpenC(false)}
|
183
|
+
opened={isOpenC}
|
184
|
+
placement="top"
|
185
|
+
offset={[offsetX, offsetY]}
|
186
|
+
hasBody
|
187
|
+
{...rest}
|
188
|
+
>
|
189
|
+
<Button style={{ marginRight: '1rem' }} onClick={() => setIsOpenC(false)}>
|
190
|
+
Close
|
191
|
+
</Button>
|
192
|
+
<>Content</>
|
193
|
+
</Modal>
|
194
|
+
</Modal>
|
195
|
+
</StyledModal>
|
196
|
+
</PopupProvider>
|
197
|
+
</StyledWrapper>
|
198
|
+
</SSRProvider>
|
199
|
+
);
|
200
|
+
};
|
201
|
+
|
202
|
+
const StoryCustomModalDemo = ({ placement, offsetX, offsetY, ...rest }: StoryModalProps) => {
|
203
|
+
const [isOpenA, setIsOpenA] = useState(false);
|
204
|
+
const [isOpenB, setIsOpenB] = useState(false);
|
205
|
+
const [isOpenC, setIsOpenC] = useState(false);
|
206
|
+
|
138
207
|
return (
|
139
208
|
<SSRProvider>
|
140
209
|
<StyledWrapper>
|
@@ -199,7 +268,7 @@ const StoryModalDemo = ({ placement, offsetX, offsetY, ...rest }: StoryModalProp
|
|
199
268
|
);
|
200
269
|
};
|
201
270
|
|
202
|
-
export const
|
271
|
+
export const Default: StoryObj<StoryModalProps> = {
|
203
272
|
args: {
|
204
273
|
placement: 'center',
|
205
274
|
withBlur: false,
|
@@ -207,10 +276,30 @@ export const ModalDemo: StoryObj<StoryModalProps> = {
|
|
207
276
|
closeOnOverlayClick: true,
|
208
277
|
offsetX: 0,
|
209
278
|
offsetY: 0,
|
279
|
+
hasClose: true,
|
280
|
+
},
|
281
|
+
argTypes: {
|
282
|
+
hasClose: {
|
283
|
+
control: {
|
284
|
+
type: 'boolean',
|
285
|
+
},
|
286
|
+
},
|
210
287
|
},
|
211
288
|
render: (args) => <StoryModalDemo {...args} />,
|
212
289
|
};
|
213
290
|
|
291
|
+
export const CustomModalDemo: StoryObj<StoryModalProps> = {
|
292
|
+
args: {
|
293
|
+
placement: 'center',
|
294
|
+
withBlur: false,
|
295
|
+
closeOnEsc: true,
|
296
|
+
closeOnOverlayClick: true,
|
297
|
+
offsetX: 0,
|
298
|
+
offsetY: 0,
|
299
|
+
},
|
300
|
+
render: (args) => <StoryCustomModalDemo {...args} />,
|
301
|
+
};
|
302
|
+
|
214
303
|
const StyledModalAnimation = styled(Modal)`
|
215
304
|
/* stylelint-disable */
|
216
305
|
&& .${popupClasses.root} {
|
@@ -1,4 +1,5 @@
|
|
1
|
-
var
|
1
|
+
var _IconClose;
|
2
|
+
var _excluded = ["id", "withAnimation", "onClose", "onOverlayClick", "onEscKeyDown", "closeOnEsc", "closeOnOverlayClick", "withBlur", "initialFocusRef", "focusAfterRef", "zIndex", "popupInfo", "children", "view", "opened", "isOpen", "hasBody", "hasClose"];
|
2
3
|
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
3
4
|
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
4
5
|
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
@@ -9,10 +10,12 @@ import { popupConfig, usePopupContext } from '../Popup';
|
|
9
10
|
import { Overlay } from '../Overlay';
|
10
11
|
import { DEFAULT_Z_INDEX } from '../Popup/utils';
|
11
12
|
import { useFocusTrap } from '../../hooks';
|
13
|
+
import { IconClose } from '../_Icon/Icons/IconClose';
|
12
14
|
import { classes, tokens } from './Modal.tokens';
|
13
15
|
import { useModal } from './hooks';
|
14
16
|
import { base as viewCSS } from './variations/_view/base';
|
15
17
|
import { getIdLastModal } from './ModalContext';
|
18
|
+
import { CloseButton, ModalBody, ModalContent } from './Modal.styles';
|
16
19
|
|
17
20
|
// issue #823
|
18
21
|
var Popup = /*#__PURE__*/component(popupConfig);
|
@@ -41,8 +44,11 @@ export var modalRoot = function modalRoot(Root) {
|
|
41
44
|
view = _ref.view,
|
42
45
|
opened = _ref.opened,
|
43
46
|
isOpen = _ref.isOpen,
|
47
|
+
hasBody = _ref.hasBody,
|
48
|
+
hasClose = _ref.hasClose,
|
44
49
|
rest = _objectWithoutProperties(_ref, _excluded);
|
45
50
|
var innerIsOpen = Boolean(isOpen || opened);
|
51
|
+
var innerHasClose = hasClose === undefined && hasBody || hasClose;
|
46
52
|
var trapRef = useFocusTrap(true, initialFocusRef, focusAfterRef, true);
|
47
53
|
var popupController = usePopupContext();
|
48
54
|
var innerRef = useForkRef(trapRef, outerRootRef);
|
@@ -70,6 +76,15 @@ export var modalRoot = function modalRoot(Root) {
|
|
70
76
|
onClose();
|
71
77
|
}
|
72
78
|
}, [closeOnOverlayClick, onOverlayClick, onClose]);
|
79
|
+
var overlayNode = /*#__PURE__*/React.createElement(Overlay, {
|
80
|
+
className: classes.overlay,
|
81
|
+
zIndex: zIndex || DEFAULT_Z_INDEX,
|
82
|
+
backgroundColorProperty: overlayBackgroundToken,
|
83
|
+
withBlur: withBlur,
|
84
|
+
transparent: transparent,
|
85
|
+
isClickable: closeOnOverlayClick,
|
86
|
+
onOverlayClick: onModalOverlayKeyDown
|
87
|
+
});
|
73
88
|
return /*#__PURE__*/React.createElement(Popup, _extends({
|
74
89
|
id: innerId,
|
75
90
|
opened: innerIsOpen,
|
@@ -77,18 +92,17 @@ export var modalRoot = function modalRoot(Root) {
|
|
77
92
|
popupInfo: modalInfo,
|
78
93
|
withAnimation: withAnimation,
|
79
94
|
zIndex: zIndex,
|
80
|
-
overlay: /*#__PURE__*/React.createElement(Root, {
|
95
|
+
overlay: hasBody ? overlayNode : /*#__PURE__*/React.createElement(Root, {
|
81
96
|
view: view
|
82
|
-
},
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
}, rest), children);
|
97
|
+
}, overlayNode)
|
98
|
+
}, rest), hasBody ? /*#__PURE__*/React.createElement(Root, {
|
99
|
+
view: view
|
100
|
+
}, /*#__PURE__*/React.createElement(ModalBody, null, /*#__PURE__*/React.createElement(ModalContent, null, innerHasClose && /*#__PURE__*/React.createElement(CloseButton, {
|
101
|
+
onClick: onClose,
|
102
|
+
"data-test": "modal-close"
|
103
|
+
}, _IconClose || (_IconClose = /*#__PURE__*/React.createElement(IconClose, {
|
104
|
+
size: "s"
|
105
|
+
}))), children))) : /*#__PURE__*/React.createElement(React.Fragment, null, children));
|
92
106
|
});
|
93
107
|
};
|
94
108
|
export var modalConfig = {
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import styled from 'styled-components';
|
2
|
+
import { addFocus } from '../../mixins';
|
3
|
+
import { tokens } from './Modal.tokens';
|
4
|
+
export var ModalBody = /*#__PURE__*/styled.div.withConfig({
|
5
|
+
componentId: "plasma-new-hope__sc-yxf3fb-0"
|
6
|
+
})(["border-radius:var(", ");padding:var(", ");background:var(", ");box-shadow:var(--shadow-down-soft-l);"], tokens.modalBodyBorderRadius, tokens.modalBodyPadding, tokens.modalBodyBackground);
|
7
|
+
export var ModalContent = /*#__PURE__*/styled.div.withConfig({
|
8
|
+
componentId: "plasma-new-hope__sc-yxf3fb-1"
|
9
|
+
})(["position:relative;padding:var(", ");"], tokens.modalContentPadding);
|
10
|
+
export var CloseButton = /*#__PURE__*/styled.button.withConfig({
|
11
|
+
componentId: "plasma-new-hope__sc-yxf3fb-2"
|
12
|
+
})(["top:0;right:0;width:1.5rem;height:1.5rem;display:flex;align-items:center;justify-content:center;border:none;border-radius:var(", ");padding:0;margin:0;outline:none;cursor:pointer;background:transparent;", ";position:absolute;"], tokens.modalCloseButtonRadius, /*#__PURE__*/addFocus({
|
13
|
+
outlineSize: '0.063rem',
|
14
|
+
outlineOffset: '-0.125rem',
|
15
|
+
outlineColor: /*#__PURE__*/"var(".concat(tokens.modalOutlineFocusColor, ")"),
|
16
|
+
outlineRadius: /*#__PURE__*/"calc(var(".concat(tokens.modalCloseButtonRadius, ") + 0.063rem)")
|
17
|
+
}));
|
@@ -62,6 +62,53 @@ export function App() {
|
|
62
62
|
}
|
63
63
|
```
|
64
64
|
|
65
|
+
## Использование стилизованной обертки
|
66
|
+
|
67
|
+
Для использования стилизованного мобального окна с отступами и крестиком для закрытия, добавьте свойство `hasBody`.
|
68
|
+
```tsx live
|
69
|
+
import React, { useState } from 'react';
|
70
|
+
import { SSRProvider, Button, Modal, PopupProvider } from '@salutejs/{{ package }}';
|
71
|
+
|
72
|
+
export function App() {
|
73
|
+
const [isOpenA, setIsOpenA] = useState(false);
|
74
|
+
const [isOpenB, setIsOpenB] = useState(false);
|
75
|
+
|
76
|
+
return (
|
77
|
+
<SSRProvider>
|
78
|
+
<PopupProvider>
|
79
|
+
<div style=\{{ height: "300px" }}>
|
80
|
+
<div style=\{{ display: 'flex', flexDirection: 'column' }}>
|
81
|
+
<Button text="Открыть A" onClick={() => setIsOpenA(true)} />
|
82
|
+
</div>
|
83
|
+
<Modal
|
84
|
+
id="modalA"
|
85
|
+
onClose={() => setIsOpenA(false)}
|
86
|
+
opened={isOpenA}
|
87
|
+
placement="center"
|
88
|
+
offset={[0, 0]}
|
89
|
+
hasBody
|
90
|
+
>
|
91
|
+
<Button onClick={() => setIsOpenA(false)}>Close</Button>
|
92
|
+
<Button text="Открыть B" onClick={() => setIsOpenB(true)} />
|
93
|
+
Content
|
94
|
+
<Modal
|
95
|
+
id="modalB"
|
96
|
+
onClose={() => setIsOpenB(false)}
|
97
|
+
opened={isOpenB}
|
98
|
+
placement="right"
|
99
|
+
offset={[0, 0]}
|
100
|
+
>
|
101
|
+
<Button onClick={() => setIsOpenB(false)}>Close</Button>
|
102
|
+
Content
|
103
|
+
</Modal>
|
104
|
+
</Modal>
|
105
|
+
</div>
|
106
|
+
</PopupProvider>
|
107
|
+
</SSRProvider>
|
108
|
+
);
|
109
|
+
}
|
110
|
+
```
|
111
|
+
|
65
112
|
## Подключение анимации
|
66
113
|
Подключение анимации аналогично тому, как это происходит в `Popup` - через свойство `withAnimation`(управление через `popupClasses`, `modalClasses`).
|
67
114
|
Для добавления анимации в оверлей необходимо использовать класс `.modal-overlay` через переменную `modalClasses.overlay` из пакета.
|
@@ -6,5 +6,11 @@ export var classes = {
|
|
6
6
|
};
|
7
7
|
export var tokens = {
|
8
8
|
modalOverlayWithBlurColor: '--plasma-modal-overlay-with-blur-color',
|
9
|
-
modalOverlayColor: '--plasma-modal-overlay-color'
|
9
|
+
modalOverlayColor: '--plasma-modal-overlay-color',
|
10
|
+
modalBodyBackground: '--plasma-modal-body-background',
|
11
|
+
modalBodyBorderRadius: '--plasma-modal-body-border-radius',
|
12
|
+
modalBodyPadding: '--plasma-modal-body-padding',
|
13
|
+
modalContentPadding: '--plasma-modal-content-padding',
|
14
|
+
modalOutlineFocusColor: '--plasma-modal-outline-focus-color',
|
15
|
+
modalCloseButtonRadius: '--plasma-modal-close-button-radius'
|
10
16
|
};
|
@@ -6,7 +6,7 @@ export var config = {
|
|
6
6
|
},
|
7
7
|
variations: {
|
8
8
|
view: {
|
9
|
-
"default": /*#__PURE__*/css(["", ":var(--overlay-blur);", ":var(--overlay-soft);"], modalTokens.modalOverlayWithBlurColor, modalTokens.modalOverlayColor)
|
9
|
+
"default": /*#__PURE__*/css(["", ":var(--overlay-blur);", ":var(--overlay-soft);", ":var(--surface-solid-card);", ":1.25rem;", ":2rem;", ":0.625rem;", ":0.375rem;", ":var(--surface-accent);"], modalTokens.modalOverlayWithBlurColor, modalTokens.modalOverlayColor, modalTokens.modalBodyBackground, modalTokens.modalBodyBorderRadius, modalTokens.modalBodyPadding, modalTokens.modalContentPadding, modalTokens.modalCloseButtonRadius, modalTokens.modalOutlineFocusColor)
|
10
10
|
}
|
11
11
|
}
|
12
12
|
};
|
@@ -3,6 +3,7 @@ import styled from 'styled-components';
|
|
3
3
|
import type { ComponentProps } from 'react';
|
4
4
|
import type { StoryObj, Meta } from '@storybook/react';
|
5
5
|
import { SSRProvider } from '@salutejs/plasma-core';
|
6
|
+
import { disableProps } from '@salutejs/plasma-sb-utils';
|
6
7
|
|
7
8
|
import { PopupProvider, popupClasses } from '../Popup/Popup';
|
8
9
|
import { Button } from '../Button/Button';
|
@@ -18,6 +19,7 @@ export default {
|
|
18
19
|
docs: { story: { inline: false, iframeHeight: '30rem' } },
|
19
20
|
},
|
20
21
|
argTypes: {
|
22
|
+
...disableProps(['hasBody']),
|
21
23
|
placement: {
|
22
24
|
options: [
|
23
25
|
'center',
|
@@ -75,6 +77,7 @@ type StoryModalProps = ComponentProps<typeof Modal> & {
|
|
75
77
|
closeOnEsc: boolean;
|
76
78
|
closeOnOverlayClick: boolean;
|
77
79
|
withBlur: boolean;
|
80
|
+
hasClose?: boolean;
|
78
81
|
};
|
79
82
|
|
80
83
|
const StyledButton = styled(Button)`
|
@@ -135,6 +138,72 @@ const StoryModalDemo = ({ placement, offsetX, offsetY, ...rest }: StoryModalProp
|
|
135
138
|
const [isOpenB, setIsOpenB] = useState(false);
|
136
139
|
const [isOpenC, setIsOpenC] = useState(false);
|
137
140
|
|
141
|
+
return (
|
142
|
+
<SSRProvider>
|
143
|
+
<StyledWrapper>
|
144
|
+
<PopupProvider>
|
145
|
+
<ButtonWrapper>
|
146
|
+
<StyledButton text="Открыть A" onClick={() => setIsOpenA(true)} />
|
147
|
+
</ButtonWrapper>
|
148
|
+
<StyledModal
|
149
|
+
id="modalA"
|
150
|
+
frame="theme-root"
|
151
|
+
withAnimation
|
152
|
+
onClose={() => setIsOpenA(false)}
|
153
|
+
opened={isOpenA}
|
154
|
+
placement={placement}
|
155
|
+
offset={[offsetX, offsetY]}
|
156
|
+
hasBody
|
157
|
+
{...rest}
|
158
|
+
>
|
159
|
+
<Button onClick={() => setIsOpenA(false)}>Close</Button>
|
160
|
+
<ButtonWrapper>
|
161
|
+
<StyledButton text="Открыть B" onClick={() => setIsOpenB(true)} />
|
162
|
+
</ButtonWrapper>
|
163
|
+
<Modal
|
164
|
+
id="modalB"
|
165
|
+
frame="theme-root"
|
166
|
+
onClose={() => setIsOpenB(false)}
|
167
|
+
opened={isOpenB}
|
168
|
+
placement="left"
|
169
|
+
offset={[offsetX, offsetY]}
|
170
|
+
hasBody
|
171
|
+
{...rest}
|
172
|
+
>
|
173
|
+
<Button style={{ marginRight: '1rem' }} onClick={() => setIsOpenB(false)}>
|
174
|
+
Close
|
175
|
+
</Button>
|
176
|
+
<ButtonWrapper>
|
177
|
+
<StyledButton text="Открыть C" onClick={() => setIsOpenC(true)} />
|
178
|
+
</ButtonWrapper>
|
179
|
+
<Modal
|
180
|
+
id="modalC"
|
181
|
+
frame="theme-root"
|
182
|
+
onClose={() => setIsOpenC(false)}
|
183
|
+
opened={isOpenC}
|
184
|
+
placement="top"
|
185
|
+
offset={[offsetX, offsetY]}
|
186
|
+
hasBody
|
187
|
+
{...rest}
|
188
|
+
>
|
189
|
+
<Button style={{ marginRight: '1rem' }} onClick={() => setIsOpenC(false)}>
|
190
|
+
Close
|
191
|
+
</Button>
|
192
|
+
<>Content</>
|
193
|
+
</Modal>
|
194
|
+
</Modal>
|
195
|
+
</StyledModal>
|
196
|
+
</PopupProvider>
|
197
|
+
</StyledWrapper>
|
198
|
+
</SSRProvider>
|
199
|
+
);
|
200
|
+
};
|
201
|
+
|
202
|
+
const StoryCustomModalDemo = ({ placement, offsetX, offsetY, ...rest }: StoryModalProps) => {
|
203
|
+
const [isOpenA, setIsOpenA] = useState(false);
|
204
|
+
const [isOpenB, setIsOpenB] = useState(false);
|
205
|
+
const [isOpenC, setIsOpenC] = useState(false);
|
206
|
+
|
138
207
|
return (
|
139
208
|
<SSRProvider>
|
140
209
|
<StyledWrapper>
|
@@ -199,7 +268,7 @@ const StoryModalDemo = ({ placement, offsetX, offsetY, ...rest }: StoryModalProp
|
|
199
268
|
);
|
200
269
|
};
|
201
270
|
|
202
|
-
export const
|
271
|
+
export const Default: StoryObj<StoryModalProps> = {
|
203
272
|
args: {
|
204
273
|
placement: 'center',
|
205
274
|
withBlur: false,
|
@@ -207,10 +276,30 @@ export const ModalDemo: StoryObj<StoryModalProps> = {
|
|
207
276
|
closeOnOverlayClick: true,
|
208
277
|
offsetX: 0,
|
209
278
|
offsetY: 0,
|
279
|
+
hasClose: true,
|
280
|
+
},
|
281
|
+
argTypes: {
|
282
|
+
hasClose: {
|
283
|
+
control: {
|
284
|
+
type: 'boolean',
|
285
|
+
},
|
286
|
+
},
|
210
287
|
},
|
211
288
|
render: (args) => <StoryModalDemo {...args} />,
|
212
289
|
};
|
213
290
|
|
291
|
+
export const CustomModalDemo: StoryObj<StoryModalProps> = {
|
292
|
+
args: {
|
293
|
+
placement: 'center',
|
294
|
+
withBlur: false,
|
295
|
+
closeOnEsc: true,
|
296
|
+
closeOnOverlayClick: true,
|
297
|
+
offsetX: 0,
|
298
|
+
offsetY: 0,
|
299
|
+
},
|
300
|
+
render: (args) => <StoryCustomModalDemo {...args} />,
|
301
|
+
};
|
302
|
+
|
214
303
|
const StyledModalAnimation = styled(Modal)`
|
215
304
|
/* stylelint-disable */
|
216
305
|
&& .${popupClasses.root} {
|
@@ -6,7 +6,7 @@ export var config = {
|
|
6
6
|
},
|
7
7
|
variations: {
|
8
8
|
view: {
|
9
|
-
"default": /*#__PURE__*/css(["", ":var(--overlay-blur);", ":var(--overlay-soft);"], modalTokens.modalOverlayWithBlurColor, modalTokens.modalOverlayColor)
|
9
|
+
"default": /*#__PURE__*/css(["", ":var(--overlay-blur);", ":var(--overlay-soft);", ":var(--surface-solid-card);", ":1.25rem;", ":2rem;", ":0.625rem;", ":0.375rem;", ":var(--surface-accent);"], modalTokens.modalOverlayWithBlurColor, modalTokens.modalOverlayColor, modalTokens.modalBodyBackground, modalTokens.modalBodyBorderRadius, modalTokens.modalBodyPadding, modalTokens.modalContentPadding, modalTokens.modalCloseButtonRadius, modalTokens.modalOutlineFocusColor)
|
10
10
|
}
|
11
11
|
}
|
12
12
|
};
|
@@ -3,6 +3,7 @@ import styled from 'styled-components';
|
|
3
3
|
import type { ComponentProps } from 'react';
|
4
4
|
import type { StoryObj, Meta } from '@storybook/react';
|
5
5
|
import { SSRProvider } from '@salutejs/plasma-core';
|
6
|
+
import { disableProps } from '@salutejs/plasma-sb-utils';
|
6
7
|
|
7
8
|
import { PopupProvider, popupClasses } from '../Popup/Popup';
|
8
9
|
import { Button } from '../Button/Button';
|
@@ -18,6 +19,7 @@ export default {
|
|
18
19
|
docs: { story: { inline: false, iframeHeight: '30rem' } },
|
19
20
|
},
|
20
21
|
argTypes: {
|
22
|
+
...disableProps(['hasBody']),
|
21
23
|
placement: {
|
22
24
|
options: [
|
23
25
|
'center',
|
@@ -75,6 +77,7 @@ type StoryModalProps = ComponentProps<typeof Modal> & {
|
|
75
77
|
closeOnEsc: boolean;
|
76
78
|
closeOnOverlayClick: boolean;
|
77
79
|
withBlur: boolean;
|
80
|
+
hasClose?: boolean;
|
78
81
|
};
|
79
82
|
|
80
83
|
const StyledButton = styled(Button)`
|
@@ -135,6 +138,72 @@ const StoryModalDemo = ({ placement, offsetX, offsetY, ...rest }: StoryModalProp
|
|
135
138
|
const [isOpenB, setIsOpenB] = useState(false);
|
136
139
|
const [isOpenC, setIsOpenC] = useState(false);
|
137
140
|
|
141
|
+
return (
|
142
|
+
<SSRProvider>
|
143
|
+
<StyledWrapper>
|
144
|
+
<PopupProvider>
|
145
|
+
<ButtonWrapper>
|
146
|
+
<StyledButton text="Открыть A" onClick={() => setIsOpenA(true)} />
|
147
|
+
</ButtonWrapper>
|
148
|
+
<StyledModal
|
149
|
+
id="modalA"
|
150
|
+
frame="theme-root"
|
151
|
+
withAnimation
|
152
|
+
onClose={() => setIsOpenA(false)}
|
153
|
+
opened={isOpenA}
|
154
|
+
placement={placement}
|
155
|
+
offset={[offsetX, offsetY]}
|
156
|
+
hasBody
|
157
|
+
{...rest}
|
158
|
+
>
|
159
|
+
<Button onClick={() => setIsOpenA(false)}>Close</Button>
|
160
|
+
<ButtonWrapper>
|
161
|
+
<StyledButton text="Открыть B" onClick={() => setIsOpenB(true)} />
|
162
|
+
</ButtonWrapper>
|
163
|
+
<Modal
|
164
|
+
id="modalB"
|
165
|
+
frame="theme-root"
|
166
|
+
onClose={() => setIsOpenB(false)}
|
167
|
+
opened={isOpenB}
|
168
|
+
placement="left"
|
169
|
+
offset={[offsetX, offsetY]}
|
170
|
+
hasBody
|
171
|
+
{...rest}
|
172
|
+
>
|
173
|
+
<Button style={{ marginRight: '1rem' }} onClick={() => setIsOpenB(false)}>
|
174
|
+
Close
|
175
|
+
</Button>
|
176
|
+
<ButtonWrapper>
|
177
|
+
<StyledButton text="Открыть C" onClick={() => setIsOpenC(true)} />
|
178
|
+
</ButtonWrapper>
|
179
|
+
<Modal
|
180
|
+
id="modalC"
|
181
|
+
frame="theme-root"
|
182
|
+
onClose={() => setIsOpenC(false)}
|
183
|
+
opened={isOpenC}
|
184
|
+
placement="top"
|
185
|
+
offset={[offsetX, offsetY]}
|
186
|
+
hasBody
|
187
|
+
{...rest}
|
188
|
+
>
|
189
|
+
<Button style={{ marginRight: '1rem' }} onClick={() => setIsOpenC(false)}>
|
190
|
+
Close
|
191
|
+
</Button>
|
192
|
+
<>Content</>
|
193
|
+
</Modal>
|
194
|
+
</Modal>
|
195
|
+
</StyledModal>
|
196
|
+
</PopupProvider>
|
197
|
+
</StyledWrapper>
|
198
|
+
</SSRProvider>
|
199
|
+
);
|
200
|
+
};
|
201
|
+
|
202
|
+
const StoryCustomModalDemo = ({ placement, offsetX, offsetY, ...rest }: StoryModalProps) => {
|
203
|
+
const [isOpenA, setIsOpenA] = useState(false);
|
204
|
+
const [isOpenB, setIsOpenB] = useState(false);
|
205
|
+
const [isOpenC, setIsOpenC] = useState(false);
|
206
|
+
|
138
207
|
return (
|
139
208
|
<SSRProvider>
|
140
209
|
<StyledWrapper>
|
@@ -199,7 +268,7 @@ const StoryModalDemo = ({ placement, offsetX, offsetY, ...rest }: StoryModalProp
|
|
199
268
|
);
|
200
269
|
};
|
201
270
|
|
202
|
-
export const
|
271
|
+
export const Default: StoryObj<StoryModalProps> = {
|
203
272
|
args: {
|
204
273
|
placement: 'center',
|
205
274
|
withBlur: false,
|
@@ -207,10 +276,30 @@ export const ModalDemo: StoryObj<StoryModalProps> = {
|
|
207
276
|
closeOnOverlayClick: true,
|
208
277
|
offsetX: 0,
|
209
278
|
offsetY: 0,
|
279
|
+
hasClose: true,
|
280
|
+
},
|
281
|
+
argTypes: {
|
282
|
+
hasClose: {
|
283
|
+
control: {
|
284
|
+
type: 'boolean',
|
285
|
+
},
|
286
|
+
},
|
210
287
|
},
|
211
288
|
render: (args) => <StoryModalDemo {...args} />,
|
212
289
|
};
|
213
290
|
|
291
|
+
export const CustomModalDemo: StoryObj<StoryModalProps> = {
|
292
|
+
args: {
|
293
|
+
placement: 'center',
|
294
|
+
withBlur: false,
|
295
|
+
closeOnEsc: true,
|
296
|
+
closeOnOverlayClick: true,
|
297
|
+
offsetX: 0,
|
298
|
+
offsetY: 0,
|
299
|
+
},
|
300
|
+
render: (args) => <StoryCustomModalDemo {...args} />,
|
301
|
+
};
|
302
|
+
|
214
303
|
const StyledModalAnimation = styled(Modal)`
|
215
304
|
/* stylelint-disable */
|
216
305
|
&& .${popupClasses.root} {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../../../src/components/Modal/Modal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAGhE,OAAO,EAAE,SAAS,EAAa,MAAM,eAAe,CAAC;
|
1
|
+
{"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../../../src/components/Modal/Modal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAGhE,OAAO,EAAE,SAAS,EAAa,MAAM,eAAe,CAAC;AAQrD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAS3C;;;GAGG;AACH,eAAO,MAAM,SAAS,SAAU,UAAU,cAAc,EAAE,UAAU,CAAC,sFA6GhE,CAAC;AAEN,eAAO,MAAM,WAAW;;;mBA/GQ,UAAU,cAAc,EAAE,UAAU,CAAC;;;;;;;;;;CA4HpE,CAAC"}
|
@@ -0,0 +1,5 @@
|
|
1
|
+
/// <reference types="react" />
|
2
|
+
export declare const ModalBody: import("@linaria/react").StyledComponent<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & Record<never, unknown>>;
|
3
|
+
export declare const ModalContent: import("@linaria/react").StyledComponent<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & Record<never, unknown>>;
|
4
|
+
export declare const CloseButton: import("@linaria/react").StyledComponent<import("react").ClassAttributes<HTMLButtonElement> & import("react").ButtonHTMLAttributes<HTMLButtonElement> & Record<never, unknown>>;
|
5
|
+
//# sourceMappingURL=Modal.styles.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"Modal.styles.d.ts","sourceRoot":"","sources":["../../../src/components/Modal/Modal.styles.ts"],"names":[],"mappings":";AAMA,eAAO,MAAM,SAAS,qKAKrB,CAAC;AAEF,eAAO,MAAM,YAAY,qKAGxB,CAAC;AAEF,eAAO,MAAM,WAAW,iLA8BvB,CAAC"}
|
@@ -4,5 +4,11 @@ export declare const classes: {
|
|
4
4
|
export declare const tokens: {
|
5
5
|
modalOverlayWithBlurColor: string;
|
6
6
|
modalOverlayColor: string;
|
7
|
+
modalBodyBackground: string;
|
8
|
+
modalBodyBorderRadius: string;
|
9
|
+
modalBodyPadding: string;
|
10
|
+
modalContentPadding: string;
|
11
|
+
modalOutlineFocusColor: string;
|
12
|
+
modalCloseButtonRadius: string;
|
7
13
|
};
|
8
14
|
//# sourceMappingURL=Modal.tokens.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"Modal.tokens.d.ts","sourceRoot":"","sources":["../../../src/components/Modal/Modal.tokens.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO;;CAKnB,CAAC;AAEF,eAAO,MAAM,MAAM
|
1
|
+
{"version":3,"file":"Modal.tokens.d.ts","sourceRoot":"","sources":["../../../src/components/Modal/Modal.tokens.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO;;CAKnB,CAAC;AAEF,eAAO,MAAM,MAAM;;;;;;;;;CASlB,CAAC"}
|
@@ -1,6 +1,25 @@
|
|
1
1
|
/// <reference types="react" />
|
2
2
|
import { PopupHookArgs, PopupProps, PopupRootProps } from '../Popup/Popup.types';
|
3
|
-
export
|
3
|
+
export declare type ModalBodyProps = {
|
4
|
+
/**
|
5
|
+
* Оборачивает children в стилизованную обертку
|
6
|
+
*/
|
7
|
+
hasBody: true;
|
8
|
+
/**
|
9
|
+
* Отображает кнопку с крестиком для закрытия
|
10
|
+
*/
|
11
|
+
hasClose?: never | boolean;
|
12
|
+
} | {
|
13
|
+
/**
|
14
|
+
* Оборачивает children в стилизованную обертку
|
15
|
+
*/
|
16
|
+
hasBody?: never | false;
|
17
|
+
/**
|
18
|
+
* Отображает кнопку с крестиком для закрытия
|
19
|
+
*/
|
20
|
+
hasClose?: never;
|
21
|
+
};
|
22
|
+
export interface CommonModalProps extends PopupProps {
|
4
23
|
/**
|
5
24
|
* Нужно ли применять blur для подложки.
|
6
25
|
*/
|
@@ -36,6 +55,7 @@ export interface ModalProps extends PopupProps {
|
|
36
55
|
onClose?: () => void;
|
37
56
|
view?: string;
|
38
57
|
}
|
58
|
+
export declare type ModalProps = CommonModalProps & ModalBodyProps;
|
39
59
|
export declare type ModalBaseRootProps = PopupRootProps & Pick<ModalProps, 'initialFocusRef' | 'focusAfterRef' | 'onClose'>;
|
40
60
|
export declare type ModalOverlayProps = Pick<PopupRootProps, 'id' | 'zIndex'> & Pick<ModalProps, 'withBlur' | 'closeOnOverlayClick' | 'onOverlayClick' | 'onClose'>;
|
41
61
|
export declare type ModalHookArgs = Pick<PopupHookArgs, 'id' | 'popupInfo' | 'isOpen'> & Pick<ModalProps, 'closeOnEsc' | 'onEscKeyDown' | 'onClose'>;
|