@automattic/vip-design-system 0.15.0 → 0.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ exports.__esModule = true;
6
+ exports.NewConfirmationDialog = void 0;
7
+
8
+ var _classnames = _interopRequireDefault(require("classnames"));
9
+
10
+ var _propTypes = _interopRequireDefault(require("prop-types"));
11
+
12
+ var _react = _interopRequireDefault(require("react"));
13
+
14
+ var _ = require("..");
15
+
16
+ var _jsxRuntime = require("theme-ui/jsx-runtime");
17
+
18
+ /** @jsxImportSource theme-ui */
19
+
20
+ /**
21
+ * External dependencies
22
+ */
23
+
24
+ /**
25
+ * Internal dependencies
26
+ */
27
+ var NewConfirmationDialogContent = function NewConfirmationDialogContent(_ref) {
28
+ var _ref$label = _ref.label,
29
+ label = _ref$label === void 0 ? 'Confirm' : _ref$label,
30
+ onConfirm = _ref.onConfirm,
31
+ onClose = _ref.onClose,
32
+ _ref$className = _ref.className,
33
+ className = _ref$className === void 0 ? null : _ref$className;
34
+ return (0, _jsxRuntime.jsx)(_.Box, {
35
+ className: (0, _classnames["default"])('vip-confirmation-dialog-component', className),
36
+ children: (0, _jsxRuntime.jsxs)(_.Flex, {
37
+ sx: {
38
+ justifyContent: 'flex-end',
39
+ mt: 4
40
+ },
41
+ children: [(0, _jsxRuntime.jsx)(_.Button, {
42
+ variant: "secondary",
43
+ sx: {
44
+ mr: 2
45
+ },
46
+ onClick: onClose,
47
+ children: "Cancel"
48
+ }), (0, _jsxRuntime.jsx)(_.NewDialog.Close, {
49
+ children: (0, _jsxRuntime.jsx)(_.Button, {
50
+ variant: "danger",
51
+ onClick: function onClick() {
52
+ onConfirm();
53
+ onClose();
54
+ },
55
+ children: label
56
+ })
57
+ })]
58
+ })
59
+ });
60
+ };
61
+
62
+ NewConfirmationDialogContent.propTypes = {
63
+ body: _propTypes["default"].node,
64
+ label: _propTypes["default"].string,
65
+ onClose: _propTypes["default"].func,
66
+ onConfirm: _propTypes["default"].func,
67
+ className: _propTypes["default"].any
68
+ };
69
+
70
+ var NewConfirmationDialog = function NewConfirmationDialog(_ref2) {
71
+ var trigger = _ref2.trigger,
72
+ onConfirm = _ref2.onConfirm,
73
+ _ref2$needsConfirm = _ref2.needsConfirm,
74
+ needsConfirm = _ref2$needsConfirm === void 0 ? true : _ref2$needsConfirm,
75
+ label = _ref2.label,
76
+ title = _ref2.title,
77
+ _ref2$body = _ref2.body,
78
+ body = _ref2$body === void 0 ? '' : _ref2$body;
79
+
80
+ var _React$useState = _react["default"].useState(false),
81
+ open = _React$useState[0],
82
+ setOpen = _React$useState[1];
83
+
84
+ var directTrigger = /*#__PURE__*/_react["default"].cloneElement(trigger, {
85
+ onClick: onConfirm
86
+ });
87
+
88
+ if (!needsConfirm) {
89
+ return directTrigger;
90
+ }
91
+
92
+ return (0, _jsxRuntime.jsx)(_.NewDialog.Root, {
93
+ open: open,
94
+ onOpenChange: setOpen,
95
+ sx: {
96
+ maxWidth: 680
97
+ },
98
+ title: title,
99
+ description: body,
100
+ content: (0, _jsxRuntime.jsx)(NewConfirmationDialogContent, {
101
+ onClose: function onClose() {
102
+ return setOpen(false);
103
+ },
104
+ onConfirm: onConfirm,
105
+ body: body,
106
+ label: label
107
+ }),
108
+ trigger: trigger
109
+ });
110
+ };
111
+
112
+ exports.NewConfirmationDialog = NewConfirmationDialog;
113
+ NewConfirmationDialog.propTypes = {
114
+ needsConfirm: _propTypes["default"].bool,
115
+ trigger: _propTypes["default"].node,
116
+ onConfirm: _propTypes["default"].func,
117
+ title: _propTypes["default"].node.isRequired,
118
+ body: _propTypes["default"].node,
119
+ label: _propTypes["default"].node
120
+ };
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ exports.__esModule = true;
6
+ exports["default"] = exports.Default = void 0;
7
+
8
+ var _react = _interopRequireDefault(require("react"));
9
+
10
+ var _ = require("..");
11
+
12
+ var _jsxRuntime = require("theme-ui/jsx-runtime");
13
+
14
+ /**
15
+ * Internal dependencies
16
+ */
17
+ var _default = {
18
+ title: 'NewConfirmationDialog',
19
+ component: _.NewConfirmationDialog
20
+ };
21
+ exports["default"] = _default;
22
+ var ConfirmationTrigger = (0, _jsxRuntime.jsx)(_.Button, {
23
+ sx: {
24
+ mr: 3
25
+ },
26
+ children: "Click to answer"
27
+ });
28
+
29
+ var Default = function Default() {
30
+ var _React$useState = _react["default"].useState('🤔'),
31
+ answer = _React$useState[0],
32
+ setAnswer = _React$useState[1];
33
+
34
+ return (0, _jsxRuntime.jsxs)(_.Box, {
35
+ children: [(0, _jsxRuntime.jsx)("p", {
36
+ children: "Confirm that your name is John doe?"
37
+ }), (0, _jsxRuntime.jsx)(_.NewConfirmationDialog, {
38
+ title: 'Are you John Doe?',
39
+ description: 'Please confirm that your name is John Doe.',
40
+ trigger: ConfirmationTrigger,
41
+ body: "A modal is used to perform more detailed actions that don\u2018t necessarily need the context behind.",
42
+ onConfirm: function onConfirm() {
43
+ return setAnswer('👍');
44
+ },
45
+ needsConfirm: true
46
+ }), (0, _jsxRuntime.jsxs)("p", {
47
+ children: ["Answer: ", answer]
48
+ })]
49
+ });
50
+ };
51
+
52
+ exports.Default = Default;
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
6
+
7
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
8
+
9
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
10
+
11
+ var _react = require("@testing-library/react");
12
+
13
+ var _jestAxe = require("jest-axe");
14
+
15
+ var _NewConfirmationDialog = require("./NewConfirmationDialog");
16
+
17
+ var _jsxRuntime = require("theme-ui/jsx-runtime");
18
+
19
+ /**
20
+ * External dependencies
21
+ */
22
+
23
+ /**
24
+ * Internal dependencies
25
+ */
26
+ var defaultProps = {
27
+ needsConfirm: true,
28
+ title: 'My Custom Title',
29
+ body: 'My Custom Text',
30
+ label: 'Submit this!',
31
+ trigger: (0, _jsxRuntime.jsx)("button", {
32
+ children: "Trigger"
33
+ })
34
+ };
35
+
36
+ var getButton = function getButton() {
37
+ return _react.screen.getByText('Trigger');
38
+ };
39
+
40
+ var getConfirmButton = function getConfirmButton() {
41
+ return _react.screen.getByText(defaultProps.label);
42
+ };
43
+
44
+ var getTitle = function getTitle() {
45
+ return _react.screen.getByRole('heading', {
46
+ level: 2
47
+ });
48
+ };
49
+
50
+ describe('<NewConfirmationDialog />', function () {
51
+ it('renders the NewConfirmationDialog component', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() {
52
+ var _render, container;
53
+
54
+ return _regenerator["default"].wrap(function _callee$(_context) {
55
+ while (1) {
56
+ switch (_context.prev = _context.next) {
57
+ case 0:
58
+ _render = (0, _react.render)((0, _jsxRuntime.jsx)(_NewConfirmationDialog.NewConfirmationDialog, (0, _extends2["default"])({}, defaultProps))), container = _render.container;
59
+ expect(getButton()).toBeInTheDocument();
60
+
61
+ _react.fireEvent.click(getButton());
62
+
63
+ expect(getTitle()).toHaveTextContent(defaultProps.title);
64
+ expect(getConfirmButton()).toBeInTheDocument(); // Check for accessibility issues
65
+
66
+ _context.t0 = expect;
67
+ _context.next = 8;
68
+ return (0, _jestAxe.axe)(container);
69
+
70
+ case 8:
71
+ _context.t1 = _context.sent;
72
+ _context.next = 11;
73
+ return (0, _context.t0)(_context.t1).toHaveNoViolations();
74
+
75
+ case 11:
76
+ case "end":
77
+ return _context.stop();
78
+ }
79
+ }
80
+ }, _callee);
81
+ })));
82
+ });
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+
5
+ var _NewConfirmationDialog = require("./NewConfirmationDialog");
6
+
7
+ exports.NewConfirmationDialog = _NewConfirmationDialog.NewConfirmationDialog;
@@ -43,7 +43,8 @@ var DialogDescription = /*#__PURE__*/_react["default"].forwardRef(function (_ref
43
43
  return (0, _jsxRuntime.jsx)(DialogPrimitive.Description, (0, _extends2["default"])({}, rest, {
44
44
  ref: forwardedRef,
45
45
  sx: {
46
- margin: 0
46
+ margin: 0,
47
+ color: 'text'
47
48
  },
48
49
  children: text
49
50
  }));
@@ -52,6 +53,6 @@ var DialogDescription = /*#__PURE__*/_react["default"].forwardRef(function (_ref
52
53
  exports.DialogDescription = DialogDescription;
53
54
  DialogDescription.displayName = 'DialogDescription';
54
55
  DialogDescription.propTypes = {
55
- description: _propTypes["default"].string,
56
+ description: _propTypes["default"].node,
56
57
  hidden: _propTypes["default"].bool
57
58
  };
@@ -40,7 +40,9 @@ var DialogTitle = function DialogTitle(_ref) {
40
40
 
41
41
  return (0, _jsxRuntime.jsx)(DialogPrimitive.Title, {
42
42
  sx: {
43
- margin: 0
43
+ margin: 0,
44
+ fontSize: 3,
45
+ fontWeight: 500
44
46
  },
45
47
  children: titleNode
46
48
  });
@@ -48,6 +50,6 @@ var DialogTitle = function DialogTitle(_ref) {
48
50
 
49
51
  exports.DialogTitle = DialogTitle;
50
52
  DialogTitle.propTypes = {
51
- title: _propTypes["default"].string,
53
+ title: _propTypes["default"].node,
52
54
  hidden: _propTypes["default"].bool
53
55
  };
@@ -51,13 +51,22 @@ var NewDialog = function NewDialog(_ref) {
51
51
  _ref$defaultOpen = _ref.defaultOpen,
52
52
  defaultOpen = _ref$defaultOpen === void 0 ? false : _ref$defaultOpen,
53
53
  _ref$allowPinchZoom = _ref.allowPinchZoom,
54
- allowPinchZoom = _ref$allowPinchZoom === void 0 ? false : _ref$allowPinchZoom;
54
+ allowPinchZoom = _ref$allowPinchZoom === void 0 ? false : _ref$allowPinchZoom,
55
+ _ref$onOpenChange = _ref.onOpenChange,
56
+ onOpenChange = _ref$onOpenChange === void 0 ? undefined : _ref$onOpenChange,
57
+ _ref$open = _ref.open,
58
+ open = _ref$open === void 0 ? undefined : _ref$open,
59
+ _ref$id = _ref.id,
60
+ id = _ref$id === void 0 ? undefined : _ref$id;
55
61
 
56
62
  if (disabled) {
57
63
  return;
58
64
  }
59
65
 
60
66
  return (0, _jsxRuntime.jsxs)(DialogPrimitive.Root, {
67
+ id: id,
68
+ open: open,
69
+ onOpenChange: onOpenChange,
61
70
  defaultOpen: defaultOpen,
62
71
  allowPinchZoom: allowPinchZoom,
63
72
  children: [trigger && (0, _jsxRuntime.jsx)(DialogPrimitive.Trigger, {
@@ -85,14 +94,17 @@ var NewDialog = function NewDialog(_ref) {
85
94
  exports.NewDialog = NewDialog;
86
95
  NewDialog.propTypes = {
87
96
  trigger: _propTypes["default"].node.isRequired,
88
- title: _propTypes["default"].string.isRequired,
89
- description: _propTypes["default"].string.isRequired,
97
+ title: _propTypes["default"].node.isRequired,
98
+ description: _propTypes["default"].node.isRequired,
90
99
  content: _propTypes["default"].node,
91
100
  showHeading: _propTypes["default"].bool,
92
101
  disabled: _propTypes["default"].bool,
93
102
  style: _propTypes["default"].oneOfType([_propTypes["default"].object, _propTypes["default"].func]),
94
103
  // Radix DialogPrimitive.Root properties
95
104
  // https://www.radix-ui.com/docs/primitives/components/dialog#root
105
+ id: _propTypes["default"].string,
106
+ open: _propTypes["default"].bool,
96
107
  defaultOpen: _propTypes["default"].bool,
97
- allowPinchZoom: _propTypes["default"].bool
108
+ allowPinchZoom: _propTypes["default"].bool,
109
+ onOpenChange: _propTypes["default"].func
98
110
  };
@@ -3,27 +3,37 @@
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
4
 
5
5
  exports.__esModule = true;
6
- exports["default"] = exports.HiddenHeadings = exports.Default = exports.CustomStyling = exports.CustomClose = exports.AutoOpen = void 0;
6
+ exports["default"] = exports.HiddenHeadings = exports.Default = exports.CustomStyling = exports.CustomStateManagement = exports.CustomClose = exports.AutoOpen = void 0;
7
7
 
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
9
 
10
+ var _react = require("react");
11
+
10
12
  var _system = require("../../system");
11
13
 
12
14
  var _ScreenReaderText = _interopRequireDefault(require("../ScreenReaderText"));
13
15
 
14
- var _ = require(".");
16
+ var NewDialog = _interopRequireWildcard(require("."));
15
17
 
16
18
  var _jsxRuntime = require("theme-ui/jsx-runtime");
17
19
 
20
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
21
+
22
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
23
+
18
24
  /** @jsxImportSource theme-ui */
19
25
 
26
+ /**
27
+ * External dependencies
28
+ */
29
+
20
30
  /**
21
31
  /**
22
32
  * Internal dependencies
23
33
  */
24
34
  var _default = {
25
35
  title: 'NewDialog',
26
- component: _.NewDialog
36
+ component: NewDialog.Root
27
37
  };
28
38
  exports["default"] = _default;
29
39
  var defaultProps = {
@@ -39,7 +49,7 @@ var Default = function Default() {
39
49
  mb: 3
40
50
  },
41
51
  children: "Regular Dialog where the title and description are built-in and the content is provided by the user."
42
- }), (0, _jsxRuntime.jsx)(_.NewDialog, (0, _extends2["default"])({}, defaultProps, {
52
+ }), (0, _jsxRuntime.jsx)(NewDialog.Root, (0, _extends2["default"])({}, defaultProps, {
43
53
  trigger: (0, _jsxRuntime.jsx)(_system.Button, {
44
54
  children: "Trigger Dialog"
45
55
  })
@@ -57,7 +67,7 @@ var AutoOpen = function AutoOpen() {
57
67
  mb: 3
58
68
  },
59
69
  children: "Auto Opens when rendered. Press escape to close it."
60
- }), (0, _jsxRuntime.jsx)(_.NewDialog, (0, _extends2["default"])({}, defaultProps, {
70
+ }), (0, _jsxRuntime.jsx)(NewDialog.Root, (0, _extends2["default"])({}, defaultProps, {
61
71
  defaultOpen: true,
62
72
  content: (0, _jsxRuntime.jsxs)("div", {
63
73
  children: [(0, _jsxRuntime.jsx)("h3", {
@@ -83,7 +93,7 @@ var HiddenHeadings = function HiddenHeadings() {
83
93
  mb: 3
84
94
  },
85
95
  children: "Title and description are hidden, but still announced using a screen reader. Activate VoiceOver or any similar screen reader to listen to: Custom dialog title, Description of the dialog content."
86
- }), (0, _jsxRuntime.jsx)(_.NewDialog, (0, _extends2["default"])({}, defaultProps, {
96
+ }), (0, _jsxRuntime.jsx)(NewDialog.Root, (0, _extends2["default"])({}, defaultProps, {
87
97
  trigger: (0, _jsxRuntime.jsx)(_system.Button, {
88
98
  children: "Trigger Dialog"
89
99
  }),
@@ -124,7 +134,7 @@ var CustomStyling = function CustomStyling() {
124
134
  mb: 3
125
135
  },
126
136
  children: "Custom Styling on Dialog Content"
127
- }), (0, _jsxRuntime.jsx)(_.NewDialog, (0, _extends2["default"])({}, defaultProps, {
137
+ }), (0, _jsxRuntime.jsx)(NewDialog.Root, (0, _extends2["default"])({}, defaultProps, {
128
138
  defaultOpen: true,
129
139
  trigger: (0, _jsxRuntime.jsx)(_system.Button, {
130
140
  children: "Trigger Dialog"
@@ -177,12 +187,12 @@ var CustomClose = function CustomClose() {
177
187
  mb: 3
178
188
  },
179
189
  children: "This example shows how you can create a custom Close trigger to your dialog"
180
- }), (0, _jsxRuntime.jsx)(_.NewDialog, (0, _extends2["default"])({}, defaultProps, {
190
+ }), (0, _jsxRuntime.jsx)(NewDialog.Root, (0, _extends2["default"])({}, defaultProps, {
181
191
  trigger: (0, _jsxRuntime.jsx)(_system.Button, {
182
192
  children: "Trigger Dialog"
183
193
  }),
184
194
  content: (0, _jsxRuntime.jsx)("div", {
185
- children: (0, _jsxRuntime.jsx)(_.Close, {
195
+ children: (0, _jsxRuntime.jsx)(NewDialog.Close, {
186
196
  children: (0, _jsxRuntime.jsx)(_system.Button, {
187
197
  children: "Close here instead"
188
198
  })
@@ -192,4 +202,40 @@ var CustomClose = function CustomClose() {
192
202
  });
193
203
  };
194
204
 
195
- exports.CustomClose = CustomClose;
205
+ exports.CustomClose = CustomClose;
206
+
207
+ var CustomStateManagement = function CustomStateManagement() {
208
+ var _useState = (0, _react.useState)(false),
209
+ open = _useState[0],
210
+ setOpen = _useState[1];
211
+
212
+ return (0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
213
+ children: [(0, _jsxRuntime.jsxs)(_system.Text, {
214
+ sx: {
215
+ fontSize: 3,
216
+ mb: 3
217
+ },
218
+ children: ["This example shows how you can create a custom state management. To achieve accessibility, you need to control the ", (0, _jsxRuntime.jsx)("strong", {
219
+ children: "open"
220
+ }), " state, but also keep consistency using the", ' ', (0, _jsxRuntime.jsx)("strong", {
221
+ children: "onOpenChange"
222
+ }), " attribute."]
223
+ }), (0, _jsxRuntime.jsx)(NewDialog.Root, (0, _extends2["default"])({}, defaultProps, {
224
+ open: open,
225
+ onOpenChange: setOpen,
226
+ trigger: (0, _jsxRuntime.jsx)(_system.Button, {
227
+ children: "Trigger Dialog"
228
+ }),
229
+ content: (0, _jsxRuntime.jsx)("div", {
230
+ children: (0, _jsxRuntime.jsx)(_system.Button, {
231
+ onClick: function onClick() {
232
+ return setOpen(false);
233
+ },
234
+ children: "Close here instead"
235
+ })
236
+ })
237
+ }))]
238
+ });
239
+ };
240
+
241
+ exports.CustomStateManagement = CustomStateManagement;
@@ -3,6 +3,7 @@
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
4
 
5
5
  exports.__esModule = true;
6
+ exports.NewDialog = void 0;
6
7
 
7
8
  var _Avatar = require("./Avatar");
8
9
 
@@ -42,14 +43,18 @@ exports.DialogMenuItem = _Dialog.DialogMenuItem;
42
43
  exports.DialogTrigger = _Dialog.DialogTrigger;
43
44
  exports.DialogContent = _Dialog.DialogContent;
44
45
 
45
- var _NewDialog = require("./NewDialog");
46
+ var NewDialog = _interopRequireWildcard(require("./NewDialog"));
46
47
 
47
- exports.NewDialog = _NewDialog.NewDialog;
48
+ exports.NewDialog = NewDialog;
48
49
 
49
50
  var _ConfirmationDialog = require("./ConfirmationDialog");
50
51
 
51
52
  exports.ConfirmationDialog = _ConfirmationDialog.ConfirmationDialog;
52
53
 
54
+ var _NewConfirmationDialog = require("./NewConfirmationDialog");
55
+
56
+ exports.NewConfirmationDialog = _NewConfirmationDialog.NewConfirmationDialog;
57
+
53
58
  var _Flex = require("./Flex");
54
59
 
55
60
  exports.Flex = _Flex.Flex;
@@ -140,4 +145,8 @@ var _Wizard = require("./Wizard");
140
145
 
141
146
  exports.Wizard = _Wizard.Wizard;
142
147
  exports.WizardStep = _Wizard.WizardStep;
143
- exports.WizardStepHorizontal = _Wizard.WizardStepHorizontal;
148
+ exports.WizardStepHorizontal = _Wizard.WizardStepHorizontal;
149
+
150
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
151
+
152
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/vip-design-system",
3
- "version": "0.15.0",
3
+ "version": "0.17.1",
4
4
  "main": "build/system/index.js",
5
5
  "scripts": {
6
6
  "build-storybook": "build-storybook",
@@ -0,0 +1,93 @@
1
+ /** @jsxImportSource theme-ui */
2
+
3
+ /**
4
+ * External dependencies
5
+ */
6
+ import classNames from 'classnames';
7
+ import PropTypes from 'prop-types';
8
+ import React from 'react';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import { NewDialog, Box, Flex, Button } from '..';
14
+
15
+ const NewConfirmationDialogContent = ( {
16
+ label = 'Confirm',
17
+ onConfirm,
18
+ onClose,
19
+ className = null,
20
+ } ) => (
21
+ <Box className={ classNames( 'vip-confirmation-dialog-component', className ) }>
22
+ <Flex sx={ { justifyContent: 'flex-end', mt: 4 } }>
23
+ <Button variant="secondary" sx={ { mr: 2 } } onClick={ onClose }>
24
+ Cancel
25
+ </Button>
26
+ <NewDialog.Close>
27
+ <Button
28
+ variant="danger"
29
+ onClick={ () => {
30
+ onConfirm();
31
+ onClose();
32
+ } }
33
+ >
34
+ { label }
35
+ </Button>
36
+ </NewDialog.Close>
37
+ </Flex>
38
+ </Box>
39
+ );
40
+
41
+ NewConfirmationDialogContent.propTypes = {
42
+ body: PropTypes.node,
43
+ label: PropTypes.string,
44
+ onClose: PropTypes.func,
45
+ onConfirm: PropTypes.func,
46
+ className: PropTypes.any,
47
+ };
48
+
49
+ const NewConfirmationDialog = ( {
50
+ trigger,
51
+ onConfirm,
52
+ needsConfirm = true,
53
+ label,
54
+ title,
55
+ body = '',
56
+ } ) => {
57
+ const [ open, setOpen ] = React.useState( false );
58
+ const directTrigger = React.cloneElement( trigger, { onClick: onConfirm } );
59
+
60
+ if ( ! needsConfirm ) {
61
+ return directTrigger;
62
+ }
63
+
64
+ return (
65
+ <NewDialog.Root
66
+ open={ open }
67
+ onOpenChange={ setOpen }
68
+ sx={ { maxWidth: 680 } }
69
+ title={ title }
70
+ description={ body }
71
+ content={
72
+ <NewConfirmationDialogContent
73
+ onClose={ () => setOpen( false ) }
74
+ onConfirm={ onConfirm }
75
+ body={ body }
76
+ label={ label }
77
+ />
78
+ }
79
+ trigger={ trigger }
80
+ />
81
+ );
82
+ };
83
+
84
+ NewConfirmationDialog.propTypes = {
85
+ needsConfirm: PropTypes.bool,
86
+ trigger: PropTypes.node,
87
+ onConfirm: PropTypes.func,
88
+ title: PropTypes.node.isRequired,
89
+ body: PropTypes.node,
90
+ label: PropTypes.node,
91
+ };
92
+
93
+ export { NewConfirmationDialog };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import React from 'react';
5
+ import { Box, NewConfirmationDialog, Button } from '..';
6
+
7
+ export default {
8
+ title: 'NewConfirmationDialog',
9
+ component: NewConfirmationDialog,
10
+ };
11
+
12
+ const ConfirmationTrigger = <Button sx={ { mr: 3 } }>Click to answer</Button>;
13
+
14
+ export const Default = () => {
15
+ const [ answer, setAnswer ] = React.useState( '🤔' );
16
+ return (
17
+ <Box>
18
+ <p>Confirm that your name is John doe?</p>
19
+ <NewConfirmationDialog
20
+ title={ 'Are you John Doe?' }
21
+ description={ 'Please confirm that your name is John Doe.' }
22
+ trigger={ ConfirmationTrigger }
23
+ body="A modal is used to perform more detailed actions that don&lsquo;t necessarily need the context
24
+ behind."
25
+ onConfirm={ () => setAnswer( '👍' ) }
26
+ needsConfirm={ true }
27
+ />
28
+
29
+ <p>Answer: { answer }</p>
30
+ </Box>
31
+ );
32
+ };
@@ -0,0 +1,39 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { fireEvent, render, screen } from '@testing-library/react';
5
+ import { axe } from 'jest-axe';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { NewConfirmationDialog } from './NewConfirmationDialog';
11
+
12
+ const defaultProps = {
13
+ needsConfirm: true,
14
+ title: 'My Custom Title',
15
+ body: 'My Custom Text',
16
+ label: 'Submit this!',
17
+ trigger: <button>Trigger</button>,
18
+ };
19
+
20
+ const getButton = () => screen.getByText( 'Trigger' );
21
+ const getConfirmButton = () => screen.getByText( defaultProps.label );
22
+ const getTitle = () => screen.getByRole( 'heading', { level: 2 } );
23
+
24
+ describe( '<NewConfirmationDialog />', () => {
25
+ it( 'renders the NewConfirmationDialog component', async () => {
26
+ const { container } = render( <NewConfirmationDialog { ...defaultProps } /> );
27
+
28
+ expect( getButton() ).toBeInTheDocument();
29
+
30
+ fireEvent.click( getButton() );
31
+
32
+ expect( getTitle() ).toHaveTextContent( defaultProps.title );
33
+
34
+ expect( getConfirmButton() ).toBeInTheDocument();
35
+
36
+ // Check for accessibility issues
37
+ await expect( await axe( container ) ).toHaveNoViolations();
38
+ } );
39
+ } );
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { NewConfirmationDialog } from './NewConfirmationDialog';
5
+
6
+ export { NewConfirmationDialog };
@@ -21,7 +21,11 @@ export const DialogDescription = React.forwardRef(
21
21
  }
22
22
 
23
23
  return (
24
- <DialogPrimitive.Description { ...rest } ref={ forwardedRef } sx={ { margin: 0 } }>
24
+ <DialogPrimitive.Description
25
+ { ...rest }
26
+ ref={ forwardedRef }
27
+ sx={ { margin: 0, color: 'text' } }
28
+ >
25
29
  { text }
26
30
  </DialogPrimitive.Description>
27
31
  );
@@ -31,6 +35,6 @@ export const DialogDescription = React.forwardRef(
31
35
  DialogDescription.displayName = 'DialogDescription';
32
36
 
33
37
  DialogDescription.propTypes = {
34
- description: PropTypes.string,
38
+ description: PropTypes.node,
35
39
  hidden: PropTypes.bool,
36
40
  };
@@ -18,10 +18,14 @@ export const DialogTitle = ( { title, hidden = false } ) => {
18
18
  titleNode = <ScreenReaderText>{ titleNode }</ScreenReaderText>;
19
19
  }
20
20
 
21
- return <DialogPrimitive.Title sx={ { margin: 0 } }>{ titleNode }</DialogPrimitive.Title>;
21
+ return (
22
+ <DialogPrimitive.Title sx={ { margin: 0, fontSize: 3, fontWeight: 500 } }>
23
+ { titleNode }
24
+ </DialogPrimitive.Title>
25
+ );
22
26
  };
23
27
 
24
28
  DialogTitle.propTypes = {
25
- title: PropTypes.string,
29
+ title: PropTypes.node,
26
30
  hidden: PropTypes.bool,
27
31
  };
@@ -26,13 +26,22 @@ export const NewDialog = ( {
26
26
  // Radix Specific Properties
27
27
  defaultOpen = false,
28
28
  allowPinchZoom = false,
29
+ onOpenChange = undefined,
30
+ open = undefined,
31
+ id = undefined,
29
32
  } ) => {
30
33
  if ( disabled ) {
31
34
  return;
32
35
  }
33
36
 
34
37
  return (
35
- <DialogPrimitive.Root defaultOpen={ defaultOpen } allowPinchZoom={ allowPinchZoom }>
38
+ <DialogPrimitive.Root
39
+ id={ id }
40
+ open={ open }
41
+ onOpenChange={ onOpenChange }
42
+ defaultOpen={ defaultOpen }
43
+ allowPinchZoom={ allowPinchZoom }
44
+ >
36
45
  { trigger && <DialogPrimitive.Trigger asChild>{ trigger }</DialogPrimitive.Trigger> }
37
46
 
38
47
  <DialogPrimitive.Portal>
@@ -55,8 +64,8 @@ export const NewDialog = ( {
55
64
 
56
65
  NewDialog.propTypes = {
57
66
  trigger: PropTypes.node.isRequired,
58
- title: PropTypes.string.isRequired,
59
- description: PropTypes.string.isRequired,
67
+ title: PropTypes.node.isRequired,
68
+ description: PropTypes.node.isRequired,
60
69
  content: PropTypes.node,
61
70
  showHeading: PropTypes.bool,
62
71
  disabled: PropTypes.bool,
@@ -64,6 +73,9 @@ NewDialog.propTypes = {
64
73
 
65
74
  // Radix DialogPrimitive.Root properties
66
75
  // https://www.radix-ui.com/docs/primitives/components/dialog#root
76
+ id: PropTypes.string,
77
+ open: PropTypes.bool,
67
78
  defaultOpen: PropTypes.bool,
68
79
  allowPinchZoom: PropTypes.bool,
80
+ onOpenChange: PropTypes.func,
69
81
  };
@@ -1,16 +1,21 @@
1
1
  /** @jsxImportSource theme-ui */
2
2
 
3
+ /**
4
+ * External dependencies
5
+ */
6
+ import { useState } from 'react';
7
+
3
8
  /**
4
9
  /**
5
10
  * Internal dependencies
6
11
  */
7
12
  import { Button, Text, Input, Label } from '../../system';
8
13
  import ScreenReaderText from '../ScreenReaderText';
9
- import { NewDialog, Close } from '.';
14
+ import * as NewDialog from '.';
10
15
 
11
16
  export default {
12
17
  title: 'NewDialog',
13
- component: NewDialog,
18
+ component: NewDialog.Root,
14
19
  };
15
20
 
16
21
  const defaultProps = {
@@ -24,14 +29,14 @@ export const Default = () => (
24
29
  Regular Dialog where the title and description are built-in and the content is provided by the
25
30
  user.
26
31
  </Text>
27
- <NewDialog { ...defaultProps } trigger={ <Button>Trigger Dialog</Button> } />
32
+ <NewDialog.Root { ...defaultProps } trigger={ <Button>Trigger Dialog</Button> } />
28
33
  </>
29
34
  );
30
35
 
31
36
  export const AutoOpen = () => (
32
37
  <>
33
38
  <Text sx={ { fontSize: 3, mb: 3 } }>Auto Opens when rendered. Press escape to close it.</Text>
34
- <NewDialog
39
+ <NewDialog.Root
35
40
  { ...defaultProps }
36
41
  defaultOpen={ true }
37
42
  content={
@@ -61,7 +66,7 @@ export const HiddenHeadings = () => (
61
66
  dialog content.
62
67
  </Text>
63
68
 
64
- <NewDialog
69
+ <NewDialog.Root
65
70
  { ...defaultProps }
66
71
  trigger={ <Button>Trigger Dialog</Button> }
67
72
  title="Custom dialog title"
@@ -88,7 +93,7 @@ export const CustomStyling = () => (
88
93
  <>
89
94
  <Text sx={ { fontSize: 3, mb: 3 } }>Custom Styling on Dialog Content</Text>
90
95
 
91
- <NewDialog
96
+ <NewDialog.Root
92
97
  { ...defaultProps }
93
98
  defaultOpen
94
99
  trigger={ <Button>Trigger Dialog</Button> }
@@ -118,16 +123,40 @@ export const CustomClose = () => (
118
123
  <Text sx={ { fontSize: 3, mb: 3 } }>
119
124
  This example shows how you can create a custom Close trigger to your dialog
120
125
  </Text>
121
- <NewDialog
126
+ <NewDialog.Root
122
127
  { ...defaultProps }
123
128
  trigger={ <Button>Trigger Dialog</Button> }
124
129
  content={
125
130
  <div>
126
- <Close>
131
+ <NewDialog.Close>
127
132
  <Button>Close here instead</Button>
128
- </Close>
133
+ </NewDialog.Close>
129
134
  </div>
130
135
  }
131
136
  />
132
137
  </>
133
138
  );
139
+ export const CustomStateManagement = () => {
140
+ const [ open, setOpen ] = useState( false );
141
+ return (
142
+ <>
143
+ <Text sx={ { fontSize: 3, mb: 3 } }>
144
+ This example shows how you can create a custom state management. To achieve accessibility,
145
+ you need to control the <strong>open</strong> state, but also keep consistency using the{ ' ' }
146
+ <strong>onOpenChange</strong> attribute.
147
+ </Text>
148
+
149
+ <NewDialog.Root
150
+ { ...defaultProps }
151
+ open={ open }
152
+ onOpenChange={ setOpen }
153
+ trigger={ <Button>Trigger Dialog</Button> }
154
+ content={
155
+ <div>
156
+ <Button onClick={ () => setOpen( false ) }>Close here instead</Button>
157
+ </div>
158
+ }
159
+ />
160
+ </>
161
+ );
162
+ };
@@ -18,8 +18,9 @@ import {
18
18
  DialogContent,
19
19
  } from './Dialog';
20
20
 
21
- import { NewDialog } from './NewDialog';
21
+ import * as NewDialog from './NewDialog';
22
22
  import { ConfirmationDialog } from './ConfirmationDialog';
23
+ import { NewConfirmationDialog } from './NewConfirmationDialog';
23
24
  import { Flex } from './Flex';
24
25
  import {
25
26
  Input,
@@ -70,6 +71,7 @@ export {
70
71
  DialogContent,
71
72
  DialogTrigger,
72
73
  ConfirmationDialog,
74
+ NewConfirmationDialog,
73
75
  Grid,
74
76
  Flex,
75
77
  Notice,