@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 '@emotion/styled';
|
|
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,20 @@
|
|
1
|
+
import _styled from "@emotion/styled/base";
|
2
|
+
import { addFocus } from '../../mixins';
|
3
|
+
import { tokens } from './Modal.tokens';
|
4
|
+
export var ModalBody = /*#__PURE__*/_styled("div", {
|
5
|
+
target: "e1gvpqag2",
|
6
|
+
label: "plasma-new-hope__ModalBody"
|
7
|
+
})("border-radius:var(", tokens.modalBodyBorderRadius, ");padding:var(", tokens.modalBodyPadding, ");background:var(", tokens.modalBodyBackground, ");box-shadow:var(--shadow-down-soft-l);" + (process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy1lbW90aW9uL2NvbXBvbmVudHMvTW9kYWwvTW9kYWwuc3R5bGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU1tQyIsImZpbGUiOiIuLi8uLi8uLi8uLi9zcmMtZW1vdGlvbi9jb21wb25lbnRzL01vZGFsL01vZGFsLnN0eWxlcy50cyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBzdHlsZWQgZnJvbSAnQGVtb3Rpb24vc3R5bGVkJztcblxuaW1wb3J0IHsgYWRkRm9jdXMgfSBmcm9tICcuLi8uLi9taXhpbnMnO1xuXG5pbXBvcnQgeyB0b2tlbnMgfSBmcm9tICcuL01vZGFsLnRva2Vucyc7XG5cbmV4cG9ydCBjb25zdCBNb2RhbEJvZHkgPSBzdHlsZWQuZGl2YFxuICAgIGJvcmRlci1yYWRpdXM6IHZhcigke3Rva2Vucy5tb2RhbEJvZHlCb3JkZXJSYWRpdXN9KTtcbiAgICBwYWRkaW5nOiB2YXIoJHt0b2tlbnMubW9kYWxCb2R5UGFkZGluZ30pO1xuICAgIGJhY2tncm91bmQ6IHZhcigke3Rva2Vucy5tb2RhbEJvZHlCYWNrZ3JvdW5kfSk7XG4gICAgYm94LXNoYWRvdzogdmFyKC0tc2hhZG93LWRvd24tc29mdC1sKTtcbmA7XG5cbmV4cG9ydCBjb25zdCBNb2RhbENvbnRlbnQgPSBzdHlsZWQuZGl2YFxuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICBwYWRkaW5nOiB2YXIoJHt0b2tlbnMubW9kYWxDb250ZW50UGFkZGluZ30pO1xuYDtcblxuZXhwb3J0IGNvbnN0IENsb3NlQnV0dG9uID0gc3R5bGVkLmJ1dHRvbmBcbiAgICB0b3A6IDA7XG4gICAgcmlnaHQ6IDA7XG5cbiAgICB3aWR0aDogMS41cmVtO1xuICAgIGhlaWdodDogMS41cmVtO1xuXG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuXG4gICAgYm9yZGVyOiBub25lO1xuICAgIGJvcmRlci1yYWRpdXM6IHZhcigke3Rva2Vucy5tb2RhbENsb3NlQnV0dG9uUmFkaXVzfSk7XG5cbiAgICBwYWRkaW5nOiAwO1xuICAgIG1hcmdpbjogMDtcbiAgICBvdXRsaW5lOiBub25lO1xuXG4gICAgY3Vyc29yOiBwb2ludGVyO1xuXG4gICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG5cbiAgICAke2FkZEZvY3VzKHtcbiAgICAgICAgb3V0bGluZVNpemU6ICcwLjA2M3JlbScsXG4gICAgICAgIG91dGxpbmVPZmZzZXQ6ICctMC4xMjVyZW0nLFxuICAgICAgICBvdXRsaW5lQ29sb3I6IGB2YXIoJHt0b2tlbnMubW9kYWxPdXRsaW5lRm9jdXNDb2xvcn0pYCxcbiAgICAgICAgb3V0bGluZVJhZGl1czogYGNhbGModmFyKCR7dG9rZW5zLm1vZGFsQ2xvc2VCdXR0b25SYWRpdXN9KSArIDAuMDYzcmVtKWAsXG4gICAgfSl9O1xuXG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuYDtcbiJdfQ== */"));
|
8
|
+
export var ModalContent = /*#__PURE__*/_styled("div", {
|
9
|
+
target: "e1gvpqag1",
|
10
|
+
label: "plasma-new-hope__ModalContent"
|
11
|
+
})("position:relative;padding:var(", tokens.modalContentPadding, ");" + (process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy1lbW90aW9uL2NvbXBvbmVudHMvTW9kYWwvTW9kYWwuc3R5bGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQWFzQyIsImZpbGUiOiIuLi8uLi8uLi8uLi9zcmMtZW1vdGlvbi9jb21wb25lbnRzL01vZGFsL01vZGFsLnN0eWxlcy50cyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBzdHlsZWQgZnJvbSAnQGVtb3Rpb24vc3R5bGVkJztcblxuaW1wb3J0IHsgYWRkRm9jdXMgfSBmcm9tICcuLi8uLi9taXhpbnMnO1xuXG5pbXBvcnQgeyB0b2tlbnMgfSBmcm9tICcuL01vZGFsLnRva2Vucyc7XG5cbmV4cG9ydCBjb25zdCBNb2RhbEJvZHkgPSBzdHlsZWQuZGl2YFxuICAgIGJvcmRlci1yYWRpdXM6IHZhcigke3Rva2Vucy5tb2RhbEJvZHlCb3JkZXJSYWRpdXN9KTtcbiAgICBwYWRkaW5nOiB2YXIoJHt0b2tlbnMubW9kYWxCb2R5UGFkZGluZ30pO1xuICAgIGJhY2tncm91bmQ6IHZhcigke3Rva2Vucy5tb2RhbEJvZHlCYWNrZ3JvdW5kfSk7XG4gICAgYm94LXNoYWRvdzogdmFyKC0tc2hhZG93LWRvd24tc29mdC1sKTtcbmA7XG5cbmV4cG9ydCBjb25zdCBNb2RhbENvbnRlbnQgPSBzdHlsZWQuZGl2YFxuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICBwYWRkaW5nOiB2YXIoJHt0b2tlbnMubW9kYWxDb250ZW50UGFkZGluZ30pO1xuYDtcblxuZXhwb3J0IGNvbnN0IENsb3NlQnV0dG9uID0gc3R5bGVkLmJ1dHRvbmBcbiAgICB0b3A6IDA7XG4gICAgcmlnaHQ6IDA7XG5cbiAgICB3aWR0aDogMS41cmVtO1xuICAgIGhlaWdodDogMS41cmVtO1xuXG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuXG4gICAgYm9yZGVyOiBub25lO1xuICAgIGJvcmRlci1yYWRpdXM6IHZhcigke3Rva2Vucy5tb2RhbENsb3NlQnV0dG9uUmFkaXVzfSk7XG5cbiAgICBwYWRkaW5nOiAwO1xuICAgIG1hcmdpbjogMDtcbiAgICBvdXRsaW5lOiBub25lO1xuXG4gICAgY3Vyc29yOiBwb2ludGVyO1xuXG4gICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG5cbiAgICAke2FkZEZvY3VzKHtcbiAgICAgICAgb3V0bGluZVNpemU6ICcwLjA2M3JlbScsXG4gICAgICAgIG91dGxpbmVPZmZzZXQ6ICctMC4xMjVyZW0nLFxuICAgICAgICBvdXRsaW5lQ29sb3I6IGB2YXIoJHt0b2tlbnMubW9kYWxPdXRsaW5lRm9jdXNDb2xvcn0pYCxcbiAgICAgICAgb3V0bGluZVJhZGl1czogYGNhbGModmFyKCR7dG9rZW5zLm1vZGFsQ2xvc2VCdXR0b25SYWRpdXN9KSArIDAuMDYzcmVtKWAsXG4gICAgfSl9O1xuXG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuYDtcbiJdfQ== */"));
|
12
|
+
export var CloseButton = /*#__PURE__*/_styled("button", {
|
13
|
+
target: "e1gvpqag0",
|
14
|
+
label: "plasma-new-hope__CloseButton"
|
15
|
+
})("top:0;right:0;width:1.5rem;height:1.5rem;display:flex;align-items:center;justify-content:center;border:none;border-radius:var(", tokens.modalCloseButtonRadius, ");padding:0;margin:0;outline:none;cursor:pointer;background:transparent;", /*#__PURE__*/addFocus({
|
16
|
+
outlineSize: '0.063rem',
|
17
|
+
outlineOffset: '-0.125rem',
|
18
|
+
outlineColor: /*#__PURE__*/"var(".concat(tokens.modalOutlineFocusColor, ")"),
|
19
|
+
outlineRadius: /*#__PURE__*/"calc(var(".concat(tokens.modalCloseButtonRadius, ") + 0.063rem)")
|
20
|
+
}), ";position:absolute;" + (process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy1lbW90aW9uL2NvbXBvbmVudHMvTW9kYWwvTW9kYWwuc3R5bGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQWtCd0MiLCJmaWxlIjoiLi4vLi4vLi4vLi4vc3JjLWVtb3Rpb24vY29tcG9uZW50cy9Nb2RhbC9Nb2RhbC5zdHlsZXMudHMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgc3R5bGVkIGZyb20gJ0BlbW90aW9uL3N0eWxlZCc7XG5cbmltcG9ydCB7IGFkZEZvY3VzIH0gZnJvbSAnLi4vLi4vbWl4aW5zJztcblxuaW1wb3J0IHsgdG9rZW5zIH0gZnJvbSAnLi9Nb2RhbC50b2tlbnMnO1xuXG5leHBvcnQgY29uc3QgTW9kYWxCb2R5ID0gc3R5bGVkLmRpdmBcbiAgICBib3JkZXItcmFkaXVzOiB2YXIoJHt0b2tlbnMubW9kYWxCb2R5Qm9yZGVyUmFkaXVzfSk7XG4gICAgcGFkZGluZzogdmFyKCR7dG9rZW5zLm1vZGFsQm9keVBhZGRpbmd9KTtcbiAgICBiYWNrZ3JvdW5kOiB2YXIoJHt0b2tlbnMubW9kYWxCb2R5QmFja2dyb3VuZH0pO1xuICAgIGJveC1zaGFkb3c6IHZhcigtLXNoYWRvdy1kb3duLXNvZnQtbCk7XG5gO1xuXG5leHBvcnQgY29uc3QgTW9kYWxDb250ZW50ID0gc3R5bGVkLmRpdmBcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgcGFkZGluZzogdmFyKCR7dG9rZW5zLm1vZGFsQ29udGVudFBhZGRpbmd9KTtcbmA7XG5cbmV4cG9ydCBjb25zdCBDbG9zZUJ1dHRvbiA9IHN0eWxlZC5idXR0b25gXG4gICAgdG9wOiAwO1xuICAgIHJpZ2h0OiAwO1xuXG4gICAgd2lkdGg6IDEuNXJlbTtcbiAgICBoZWlnaHQ6IDEuNXJlbTtcblxuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcblxuICAgIGJvcmRlcjogbm9uZTtcbiAgICBib3JkZXItcmFkaXVzOiB2YXIoJHt0b2tlbnMubW9kYWxDbG9zZUJ1dHRvblJhZGl1c30pO1xuXG4gICAgcGFkZGluZzogMDtcbiAgICBtYXJnaW46IDA7XG4gICAgb3V0bGluZTogbm9uZTtcblxuICAgIGN1cnNvcjogcG9pbnRlcjtcblxuICAgIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xuXG4gICAgJHthZGRGb2N1cyh7XG4gICAgICAgIG91dGxpbmVTaXplOiAnMC4wNjNyZW0nLFxuICAgICAgICBvdXRsaW5lT2Zmc2V0OiAnLTAuMTI1cmVtJyxcbiAgICAgICAgb3V0bGluZUNvbG9yOiBgdmFyKCR7dG9rZW5zLm1vZGFsT3V0bGluZUZvY3VzQ29sb3J9KWAsXG4gICAgICAgIG91dGxpbmVSYWRpdXM6IGBjYWxjKHZhcigke3Rva2Vucy5tb2RhbENsb3NlQnV0dG9uUmFkaXVzfSkgKyAwLjA2M3JlbSlgLFxuICAgIH0pfTtcblxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbmA7XG4iXX0= */"));
|
@@ -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(modalTokens.modalOverlayWithBlurColor, ":var(--overlay-blur);", modalTokens.modalOverlayColor, ":var(--overlay-soft);;label:plasma-new-hope__default;" + (process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,
|
9
|
+
"default": /*#__PURE__*/css(modalTokens.modalOverlayWithBlurColor, ":var(--overlay-blur);", modalTokens.modalOverlayColor, ":var(--overlay-soft);", modalTokens.modalBodyBackground, ":var(--surface-solid-card);", modalTokens.modalBodyBorderRadius, ":1.25rem;", modalTokens.modalBodyPadding, ":2rem;", modalTokens.modalContentPadding, ":0.625rem;", modalTokens.modalCloseButtonRadius, ":0.375rem;", modalTokens.modalOutlineFocusColor, ":var(--surface-accent);;label:plasma-new-hope__default;" + (process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy1lbW90aW9uL2V4YW1wbGVzL3BsYXNtYV9iMmMvY29tcG9uZW50cy9Nb2RhbC9Nb2RhbC5jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBVXdCIiwiZmlsZSI6Ii4uLy4uLy4uLy4uLy4uLy4uL3NyYy1lbW90aW9uL2V4YW1wbGVzL3BsYXNtYV9iMmMvY29tcG9uZW50cy9Nb2RhbC9Nb2RhbC5jb25maWcudHMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjc3MgfSBmcm9tICdAZW1vdGlvbi9yZWFjdCc7XG5cbmltcG9ydCB7IG1vZGFsVG9rZW5zIH0gZnJvbSAnLi4vLi4vLi4vLi4vY29tcG9uZW50cy9Nb2RhbCc7XG5cbmV4cG9ydCBjb25zdCBjb25maWcgPSB7XG4gICAgZGVmYXVsdHM6IHtcbiAgICAgICAgdmlldzogJ2RlZmF1bHQnLFxuICAgIH0sXG4gICAgdmFyaWF0aW9uczoge1xuICAgICAgICB2aWV3OiB7XG4gICAgICAgICAgICBkZWZhdWx0OiBjc3NgXG4gICAgICAgICAgICAgICAgJHttb2RhbFRva2Vucy5tb2RhbE92ZXJsYXlXaXRoQmx1ckNvbG9yfTogdmFyKC0tb3ZlcmxheS1ibHVyKTtcbiAgICAgICAgICAgICAgICAke21vZGFsVG9rZW5zLm1vZGFsT3ZlcmxheUNvbG9yfTogdmFyKC0tb3ZlcmxheS1zb2Z0KTtcbiAgICAgICAgICAgICAgICAke21vZGFsVG9rZW5zLm1vZGFsQm9keUJhY2tncm91bmR9OiB2YXIoLS1zdXJmYWNlLXNvbGlkLWNhcmQpO1xuICAgICAgICAgICAgICAgICR7bW9kYWxUb2tlbnMubW9kYWxCb2R5Qm9yZGVyUmFkaXVzfTogMS4yNXJlbTtcbiAgICAgICAgICAgICAgICAke21vZGFsVG9rZW5zLm1vZGFsQm9keVBhZGRpbmd9OiAycmVtO1xuICAgICAgICAgICAgICAgICR7bW9kYWxUb2tlbnMubW9kYWxDb250ZW50UGFkZGluZ306IDAuNjI1cmVtO1xuICAgICAgICAgICAgICAgICR7bW9kYWxUb2tlbnMubW9kYWxDbG9zZUJ1dHRvblJhZGl1c306IDAuMzc1cmVtO1xuICAgICAgICAgICAgICAgICR7bW9kYWxUb2tlbnMubW9kYWxPdXRsaW5lRm9jdXNDb2xvcn06IHZhcigtLXN1cmZhY2UtYWNjZW50KTtcbiAgICAgICAgICAgIGAsXG4gICAgICAgIH0sXG4gICAgfSxcbn07XG4iXX0= */"))
|
10
10
|
}
|
11
11
|
}
|
12
12
|
};
|
@@ -3,6 +3,7 @@ import styled from '@emotion/styled';
|
|
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(modalTokens.modalOverlayWithBlurColor, ":var(--overlay-blur);", modalTokens.modalOverlayColor, ":var(--overlay-soft);;label:plasma-new-hope__default;" + (process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,
|
9
|
+
"default": /*#__PURE__*/css(modalTokens.modalOverlayWithBlurColor, ":var(--overlay-blur);", modalTokens.modalOverlayColor, ":var(--overlay-soft);", modalTokens.modalBodyBackground, ":var(--surface-solid-card);", modalTokens.modalBodyBorderRadius, ":1.25rem;", modalTokens.modalBodyPadding, ":2rem;", modalTokens.modalContentPadding, ":0.625rem;", modalTokens.modalCloseButtonRadius, ":0.375rem;", modalTokens.modalOutlineFocusColor, ":var(--surface-accent);;label:plasma-new-hope__default;" + (process.env.NODE_ENV === "production" ? "" : "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy1lbW90aW9uL2V4YW1wbGVzL3BsYXNtYV93ZWIvY29tcG9uZW50cy9Nb2RhbC9Nb2RhbC5jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBVXdCIiwiZmlsZSI6Ii4uLy4uLy4uLy4uLy4uLy4uL3NyYy1lbW90aW9uL2V4YW1wbGVzL3BsYXNtYV93ZWIvY29tcG9uZW50cy9Nb2RhbC9Nb2RhbC5jb25maWcudHMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjc3MgfSBmcm9tICdAZW1vdGlvbi9yZWFjdCc7XG5cbmltcG9ydCB7IG1vZGFsVG9rZW5zIH0gZnJvbSAnLi4vLi4vLi4vLi4vY29tcG9uZW50cy9Nb2RhbCc7XG5cbmV4cG9ydCBjb25zdCBjb25maWcgPSB7XG4gICAgZGVmYXVsdHM6IHtcbiAgICAgICAgdmlldzogJ2RlZmF1bHQnLFxuICAgIH0sXG4gICAgdmFyaWF0aW9uczoge1xuICAgICAgICB2aWV3OiB7XG4gICAgICAgICAgICBkZWZhdWx0OiBjc3NgXG4gICAgICAgICAgICAgICAgJHttb2RhbFRva2Vucy5tb2RhbE92ZXJsYXlXaXRoQmx1ckNvbG9yfTogdmFyKC0tb3ZlcmxheS1ibHVyKTtcbiAgICAgICAgICAgICAgICAke21vZGFsVG9rZW5zLm1vZGFsT3ZlcmxheUNvbG9yfTogdmFyKC0tb3ZlcmxheS1zb2Z0KTtcbiAgICAgICAgICAgICAgICAke21vZGFsVG9rZW5zLm1vZGFsQm9keUJhY2tncm91bmR9OiB2YXIoLS1zdXJmYWNlLXNvbGlkLWNhcmQpO1xuICAgICAgICAgICAgICAgICR7bW9kYWxUb2tlbnMubW9kYWxCb2R5Qm9yZGVyUmFkaXVzfTogMS4yNXJlbTtcbiAgICAgICAgICAgICAgICAke21vZGFsVG9rZW5zLm1vZGFsQm9keVBhZGRpbmd9OiAycmVtO1xuICAgICAgICAgICAgICAgICR7bW9kYWxUb2tlbnMubW9kYWxDb250ZW50UGFkZGluZ306IDAuNjI1cmVtO1xuICAgICAgICAgICAgICAgICR7bW9kYWxUb2tlbnMubW9kYWxDbG9zZUJ1dHRvblJhZGl1c306IDAuMzc1cmVtO1xuICAgICAgICAgICAgICAgICR7bW9kYWxUb2tlbnMubW9kYWxPdXRsaW5lRm9jdXNDb2xvcn06IHZhcigtLXN1cmZhY2UtYWNjZW50KTtcbiAgICAgICAgICAgIGAsXG4gICAgICAgIH0sXG4gICAgfSxcbn07XG4iXX0= */"))
|
10
10
|
}
|
11
11
|
}
|
12
12
|
};
|
@@ -3,6 +3,7 @@ import styled from '@emotion/styled';
|
|
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} {
|
@@ -4,3 +4,9 @@
|
|
4
4
|
.Popup_styles_gq4luz_p1f40oul__bb610b96{position:var(--p1f40oul-0);z-index:var(--p1f40oul-1);left:var(--p1f40oul-2);right:var(--p1f40oul-3);top:var(--p1f40oul-4);bottom:var(--p1f40oul-5);-webkit-transform:var(--p1f40oul-6);-ms-transform:var(--p1f40oul-6);transform:var(--p1f40oul-6);}
|
5
5
|
|
6
6
|
.Overlay_styles_cxej3y_s1afr8la__70d4dd9a{position:fixed;inset:0;z-index:var(--s1afr8la-0);--plasma_private-overlay-background-color:var(--s1afr8la-1);--plasma_private-overlay-backdrop-filter:var(--s1afr8la-2);background:var(--s1afr8la-3);-webkit-backdrop-filter:var(--s1afr8la-4);backdrop-filter:var(--s1afr8la-4);cursor:var(--s1afr8la-5);}
|
7
|
+
|
8
|
+
.IconRoot_7pl7ig_svvlqhf__32c458a1{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;width:var(--svvlqhf-0);height:var(--svvlqhf-0);-webkit-flex:0 0 var(--svvlqhf-0);-ms-flex:0 0 var(--svvlqhf-0);flex:0 0 var(--svvlqhf-0);}
|
9
|
+
|
10
|
+
.Modal_styles_tqsxxy_m7npn1w__53552e6a{border-radius:var(--plasma-modal-body-border-radius);padding:var(--plasma-modal-body-padding);background:var(--plasma-modal-body-background);box-shadow:var(--shadow-down-soft-l);}
|
11
|
+
.Modal_styles_tqsxxy_m16phoaz__53552e6a{position:relative;padding:var(--plasma-modal-content-padding);}
|
12
|
+
.Modal_styles_tqsxxy_c5bx5hr__53552e6a{top:0;right:0;width:1.5rem;height:1.5rem;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;border:none;border-radius:var(--plasma-modal-close-button-radius);padding:0;margin:0;outline:none;cursor:pointer;background:transparent;position:relative;position:absolute;}.Modal_styles_tqsxxy_c5bx5hr__53552e6a::before{content:'';position:absolute;top:-0.125rem;left:-0.125rem;right:-0.125rem;bottom:-0.125rem;z-index:1;display:block;box-sizing:content-box;border:0.063rem solid transparent;border-radius:calc(var(--plasma-modal-close-button-radius) + 0.063rem);-webkit-transition:box-shadow 0.2s ease-in-out;transition:box-shadow 0.2s ease-in-out;pointer-events:none;}.Modal_styles_tqsxxy_c5bx5hr__53552e6a.Modal_styles_tqsxxy_focusVisible__53552e6a:focus::before,.Modal_styles_tqsxxy_c5bx5hr__53552e6a[data-focus-visible-added]::before{outline:none;box-shadow:0 0 0 0.063rem var(--plasma-modal-outline-focus-color);}
|