@automattic/vip-design-system 0.26.1 → 0.26.2

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.
Files changed (32) hide show
  1. package/.storybook/preview.js +6 -0
  2. package/build/system/Accordion/Accordion.js +5 -4
  3. package/build/system/Form/Checkbox.stories.js +85 -0
  4. package/build/system/Form/Input.js +55 -31
  5. package/build/system/Form/Input.stories.js +34 -4
  6. package/build/system/Form/Radio.stories.js +95 -0
  7. package/build/system/Form/Select.stories.js +1 -1
  8. package/build/system/Form/Textarea.js +14 -53
  9. package/build/system/Form/Textarea.stories.js +67 -0
  10. package/build/system/Form/Validation.js +17 -10
  11. package/build/system/NewConfirmationDialog/NewConfirmationDialog.stories.js +1 -1
  12. package/build/system/NewDialog/NewDialog.stories.js +1 -1
  13. package/build/system/NewForm/index.js +12 -0
  14. package/build/system/NewTabs/Tabs.stories.js +11 -5
  15. package/build/system/NewTabs/TabsList.js +1 -1
  16. package/build/system/Tabs/Tabs.stories.js +1 -1
  17. package/package.json +1 -1
  18. package/src/system/Accordion/Accordion.js +2 -1
  19. package/src/system/Form/Checkbox.stories.jsx +54 -0
  20. package/src/system/Form/Input.js +44 -27
  21. package/src/system/Form/Input.stories.jsx +29 -4
  22. package/src/system/Form/Radio.stories.jsx +66 -0
  23. package/src/system/Form/Select.stories.jsx +1 -1
  24. package/src/system/Form/Textarea.js +4 -49
  25. package/src/system/Form/Textarea.stories.jsx +40 -0
  26. package/src/system/Form/Validation.js +14 -8
  27. package/src/system/NewConfirmationDialog/NewConfirmationDialog.stories.jsx +1 -1
  28. package/src/system/NewDialog/NewDialog.stories.jsx +1 -1
  29. package/src/system/NewForm/index.js +4 -1
  30. package/src/system/NewTabs/Tabs.stories.jsx +7 -3
  31. package/src/system/NewTabs/TabsList.js +1 -1
  32. package/src/system/Tabs/Tabs.stories.jsx +1 -1
@@ -13,4 +13,10 @@ export const parameters = {
13
13
  actions: { argTypesRegex: '^on[A-Z].*' },
14
14
  controls: { expanded: true },
15
15
  backgrounds,
16
+ options: {
17
+ storySort: {
18
+ method: 'alphabetical',
19
+ order: [ '*', 'Deprecated' ],
20
+ },
21
+ },
16
22
  };
@@ -116,6 +116,9 @@ var Trigger = /*#__PURE__*/_react["default"].forwardRef(function (_ref2, forward
116
116
  backgroundColor: 'backgroundSecondary',
117
117
  borderBottom: function borderBottom(theme) {
118
118
  return "1px solid " + theme.colors.border;
119
+ },
120
+ '.vip-accordion-trigger-indicator': {
121
+ transform: 'rotate(270deg)'
119
122
  }
120
123
  },
121
124
  '&:hover': {
@@ -125,14 +128,12 @@ var Trigger = /*#__PURE__*/_react["default"].forwardRef(function (_ref2, forward
125
128
  }, props, {
126
129
  ref: forwardedRef,
127
130
  children: [children, (0, _jsxRuntime.jsx)(_md.MdChevronRight, {
131
+ className: "vip-accordion-trigger-indicator",
128
132
  sx: {
129
133
  fontSize: 3,
130
134
  color: 'text',
131
135
  transform: 'rotate(90deg)',
132
- transition: 'transform 300ms cubic-bezier(0.87, 0, 0.13, 1)',
133
- '[data-state=open] &': {
134
- transform: 'rotate(270deg)'
135
- }
136
+ transition: 'transform 300ms cubic-bezier(0.87, 0, 0.13, 1)'
136
137
  },
137
138
  "aria-hidden": true
138
139
  })]
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports["default"] = exports.Default = void 0;
5
+
6
+ var _react = require("react");
7
+
8
+ var _ = require("..");
9
+
10
+ var _Checkbox = require("./Checkbox");
11
+
12
+ var _Label = require("./Label");
13
+
14
+ var _Flex = require("../Flex");
15
+
16
+ var _jsxRuntime = require("theme-ui/jsx-runtime");
17
+
18
+ /**
19
+ * External dependencies
20
+ */
21
+
22
+ /**
23
+ * Internal dependencies
24
+ */
25
+ var _default = {
26
+ title: 'Form/Checkbox',
27
+ component: _Checkbox.Checkbox
28
+ };
29
+ exports["default"] = _default;
30
+
31
+ var Default = function Default() {
32
+ var _useState = (0, _react.useState)(true),
33
+ checked = _useState[0],
34
+ setChecked = _useState[1];
35
+
36
+ var _useState2 = (0, _react.useState)(false),
37
+ checked2 = _useState2[0],
38
+ setChecked2 = _useState2[1];
39
+
40
+ return (0, _jsxRuntime.jsx)(_.Form.Root, {
41
+ children: (0, _jsxRuntime.jsxs)("fieldset", {
42
+ children: [(0, _jsxRuntime.jsx)("legend", {
43
+ children: "Tell me your prefereces"
44
+ }), (0, _jsxRuntime.jsxs)(_Flex.Flex, {
45
+ sx: {
46
+ alignItems: 'center'
47
+ },
48
+ children: [(0, _jsxRuntime.jsx)(_Checkbox.Checkbox, {
49
+ id: "check1",
50
+ checked: checked,
51
+ "aria-labelledby": "label-check1",
52
+ onCheckedChange: setChecked
53
+ }), (0, _jsxRuntime.jsx)(_Label.Label, {
54
+ sx: {
55
+ m: 0,
56
+ ml: 2
57
+ },
58
+ htmlFor: "check1",
59
+ id: "label-check1",
60
+ children: "This option"
61
+ })]
62
+ }), (0, _jsxRuntime.jsxs)(_Flex.Flex, {
63
+ sx: {
64
+ alignItems: 'center'
65
+ },
66
+ children: [(0, _jsxRuntime.jsx)(_Checkbox.Checkbox, {
67
+ id: "check2",
68
+ checked: checked2,
69
+ "aria-labelledby": "label-check2",
70
+ onCheckedChange: setChecked2
71
+ }), (0, _jsxRuntime.jsx)(_Label.Label, {
72
+ sx: {
73
+ m: 0,
74
+ ml: 2
75
+ },
76
+ htmlFor: "check2",
77
+ id: "label-check2",
78
+ children: "This option too"
79
+ })]
80
+ })]
81
+ })
82
+ });
83
+ };
84
+
85
+ exports.Default = Default;
@@ -15,9 +15,51 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
15
15
 
16
16
  var _ = require("../");
17
17
 
18
+ var _themeUi = require("theme-ui");
19
+
18
20
  var _jsxRuntime = require("theme-ui/jsx-runtime");
19
21
 
20
- var _excluded = ["variant", "label", "forLabel", "hasError", "required", "errorMessage"];
22
+ var _excluded = ["variant", "label", "forLabel", "hasError", "required", "sx", "errorMessage"];
23
+
24
+ var RequiredLabel = function RequiredLabel() {
25
+ return (0, _jsxRuntime.jsx)("span", {
26
+ sx: {
27
+ color: 'error',
28
+ display: 'inline-block',
29
+ ml: 2,
30
+ fontSize: 1
31
+ },
32
+ children: "(Required)"
33
+ });
34
+ };
35
+
36
+ var inputStyles = {
37
+ unset: 'all',
38
+ border: '1px solid',
39
+ borderColor: 'border',
40
+ backgroundColor: 'card',
41
+ borderRadius: 1,
42
+ lineHeight: 'inherit',
43
+ px: 3,
44
+ py: 2,
45
+ fontSize: 2,
46
+ mb: 2,
47
+ color: 'text',
48
+ display: 'block',
49
+ width: '100%',
50
+ '&:focus': function focus(theme) {
51
+ return theme.outline;
52
+ },
53
+ '&:focus-visible': function focusVisible(theme) {
54
+ return theme.outline;
55
+ },
56
+ '&:disabled': {
57
+ bg: 'backgroundSecondary'
58
+ },
59
+ '&::placeholder': {
60
+ color: 'placeholder'
61
+ }
62
+ };
21
63
 
22
64
  var Input = /*#__PURE__*/_react["default"].forwardRef(function (_ref, ref) {
23
65
  var variant = _ref.variant,
@@ -25,43 +67,24 @@ var Input = /*#__PURE__*/_react["default"].forwardRef(function (_ref, ref) {
25
67
  forLabel = _ref.forLabel,
26
68
  hasError = _ref.hasError,
27
69
  required = _ref.required,
70
+ _ref$sx = _ref.sx,
71
+ sx = _ref$sx === void 0 ? {} : _ref$sx,
28
72
  errorMessage = _ref.errorMessage,
29
73
  props = (0, _objectWithoutPropertiesLoose2["default"])(_ref, _excluded);
30
74
  return (0, _jsxRuntime.jsxs)(_react["default"].Fragment, {
31
75
  children: [label && (0, _jsxRuntime.jsxs)(_.Label, {
32
76
  htmlFor: forLabel,
33
- children: [label, required && '*']
34
- }), (0, _jsxRuntime.jsx)("input", (0, _extends2["default"])({}, props, {
77
+ children: [label, required && (0, _jsxRuntime.jsx)(RequiredLabel, {})]
78
+ }), (0, _jsxRuntime.jsx)(_themeUi.Input, (0, _extends2["default"])({
35
79
  ref: ref,
36
80
  id: forLabel,
37
81
  required: required,
38
- sx: {
39
- border: '1px solid',
40
- borderColor: 'border',
41
- backgroundColor: 'card',
42
- borderRadius: 1,
43
- lineHeight: 'inherit',
44
- px: 3,
45
- py: 2,
46
- fontSize: 2,
47
- mb: 2,
48
- color: 'text',
49
- display: 'block',
50
- width: '100%',
51
- '&:focus': function focus(theme) {
52
- return theme.outline;
53
- },
54
- '&:focus-visible': function focusVisible(theme) {
55
- return theme.outline;
56
- },
57
- '&:disabled': {
58
- bg: 'backgroundSecondary'
59
- },
60
- '&::placeholder': {
61
- color: 'placeholder'
62
- }
63
- }
64
- })), hasError && errorMessage && (0, _jsxRuntime.jsx)(_.Validation, {
82
+ noValidate: true,
83
+ "aria-describedby": hasError ? "describe-" + forLabel + "-validation" : undefined,
84
+ sx: (0, _extends2["default"])({}, inputStyles, sx)
85
+ }, props)), hasError && errorMessage && (0, _jsxRuntime.jsx)(_.Validation, {
86
+ isValid: false,
87
+ describedId: forLabel,
65
88
  children: errorMessage
66
89
  })]
67
90
  });
@@ -74,6 +97,7 @@ Input.propTypes = {
74
97
  hasError: _propTypes["default"].bool,
75
98
  required: _propTypes["default"].bool,
76
99
  forLabel: _propTypes["default"].string,
77
- errorMessage: _propTypes["default"].string
100
+ errorMessage: _propTypes["default"].string,
101
+ sx: _propTypes["default"].object
78
102
  };
79
103
  Input.displayName = 'Input';
@@ -13,14 +13,44 @@ var _jsxRuntime = require("theme-ui/jsx-runtime");
13
13
  * Internal dependencies
14
14
  */
15
15
  var _default = {
16
- title: 'Input',
17
- component: _.Input
16
+ title: 'Form/Input'
18
17
  };
19
18
  exports["default"] = _default;
20
19
 
21
20
  var Default = function Default() {
22
- return (0, _jsxRuntime.jsx)(_.Input, {
23
- placeholder: "Your input here..."
21
+ return (0, _jsxRuntime.jsxs)(_.Form.Root, {
22
+ children: [(0, _jsxRuntime.jsx)(_.Form.Input, {
23
+ placeholder: "Your input here...",
24
+ label: "Always add a label to inputs",
25
+ forLabel: "input-simple"
26
+ }), (0, _jsxRuntime.jsx)("hr", {
27
+ sx: {
28
+ my: 4
29
+ }
30
+ }), (0, _jsxRuntime.jsx)(_.Form.Input, {
31
+ forLabel: "input-with-error",
32
+ label: "Error Input",
33
+ errorMessage: "Please type numeric characters only",
34
+ hasError: true
35
+ }), (0, _jsxRuntime.jsx)("hr", {
36
+ sx: {
37
+ my: 4
38
+ }
39
+ }), (0, _jsxRuntime.jsx)(_.Form.Input, {
40
+ forLabel: "input-with-required",
41
+ label: "Required",
42
+ required: true
43
+ }), (0, _jsxRuntime.jsx)("hr", {
44
+ sx: {
45
+ my: 4
46
+ }
47
+ }), (0, _jsxRuntime.jsx)(_.Form.Label, {
48
+ htmlFor: "input-with-custom-label",
49
+ children: "Custom Label outside the Input"
50
+ }), (0, _jsxRuntime.jsx)(_.Form.Input, {
51
+ forLabel: "input-with-custom-label",
52
+ required: true
53
+ })]
24
54
  });
25
55
  };
26
56
 
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports["default"] = exports.Default = void 0;
5
+
6
+ var _react = require("react");
7
+
8
+ var _ = require("..");
9
+
10
+ var _Radio = require("./Radio");
11
+
12
+ var _Label = require("./Label");
13
+
14
+ var _Flex = require("../Flex");
15
+
16
+ var _jsxRuntime = require("theme-ui/jsx-runtime");
17
+
18
+ /**
19
+ * External dependencies
20
+ */
21
+
22
+ /**
23
+ * Internal dependencies
24
+ */
25
+ var _default = {
26
+ title: 'Form/Radio',
27
+ component: _Radio.Radio
28
+ };
29
+ exports["default"] = _default;
30
+
31
+ var Default = function Default() {
32
+ var _useState = (0, _react.useState)('a'),
33
+ checked = _useState[0],
34
+ setChecked = _useState[1];
35
+
36
+ return (0, _jsxRuntime.jsxs)(_.Form.Root, {
37
+ children: [(0, _jsxRuntime.jsxs)("p", {
38
+ children: ["Per recommendation, if you have a Radio button, use a Fieldset with a legend as wrapper to your options.", ' ', (0, _jsxRuntime.jsx)("a", {
39
+ href: "https://a11y-collective.github.io/demos/en/accessible-code/form-fieldsets.html",
40
+ children: "Reference to Form fieldsets"
41
+ })]
42
+ }), (0, _jsxRuntime.jsxs)("fieldset", {
43
+ children: [(0, _jsxRuntime.jsx)("legend", {
44
+ sx: {
45
+ mb: 0,
46
+ fontSize: 2,
47
+ fontWeight: 'bold'
48
+ },
49
+ children: "Apply the policy to these domains"
50
+ }), (0, _jsxRuntime.jsxs)(_Flex.Flex, {
51
+ sx: {
52
+ alignItems: 'center'
53
+ },
54
+ children: [(0, _jsxRuntime.jsx)(_Radio.Radio, {
55
+ name: "includeSubdomains",
56
+ id: "include-all-domains-opt",
57
+ onChange: function onChange() {
58
+ return setChecked('a');
59
+ },
60
+ value: 'a',
61
+ checked: checked === 'a'
62
+ }), (0, _jsxRuntime.jsx)(_Label.Label, {
63
+ htmlFor: "include-all-domains-opt",
64
+ sx: {
65
+ mb: 0
66
+ },
67
+ children: "All domains listed on this environment, and all subdomains"
68
+ })]
69
+ }), (0, _jsxRuntime.jsxs)(_Flex.Flex, {
70
+ sx: {
71
+ alignItems: 'center',
72
+ mb: 1
73
+ },
74
+ children: [(0, _jsxRuntime.jsx)(_Radio.Radio, {
75
+ name: "includeSubdomains",
76
+ id: "include-subdomains-opt",
77
+ onChange: function onChange() {
78
+ return setChecked('b');
79
+ },
80
+ checked: checked === 'b',
81
+ value: 'b'
82
+ }), (0, _jsxRuntime.jsx)(_Label.Label, {
83
+ id: "exclude-subdomains",
84
+ htmlFor: "include-subdomains-opt",
85
+ sx: {
86
+ mb: 0
87
+ },
88
+ children: "All domains listed on this environment"
89
+ })]
90
+ })]
91
+ })]
92
+ });
93
+ };
94
+
95
+ exports.Default = Default;
@@ -23,7 +23,7 @@ var _jsxRuntime = require("theme-ui/jsx-runtime");
23
23
  * Internal dependencies
24
24
  */
25
25
  var _default = {
26
- title: 'Select',
26
+ title: 'Deprecated/Select',
27
27
  component: _.Dialog
28
28
  };
29
29
  exports["default"] = _default;
@@ -7,66 +7,27 @@ exports.Textarea = void 0;
7
7
 
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
9
 
10
- var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
11
-
12
10
  var _react = _interopRequireDefault(require("react"));
13
11
 
14
- var _propTypes = _interopRequireDefault(require("prop-types"));
15
-
16
- var _ = require("../");
12
+ var _Input = require("./Input");
17
13
 
18
14
  var _jsxRuntime = require("theme-ui/jsx-runtime");
19
15
 
20
- var _excluded = ["variant", "label", "forLabel", "hasError", "required", "errorMessage"];
16
+ /** @jsxImportSource theme-ui */
17
+
18
+ /**
19
+ * External dependencies
20
+ */
21
21
 
22
- var Textarea = /*#__PURE__*/_react["default"].forwardRef(function (_ref, ref) {
23
- var variant = _ref.variant,
24
- label = _ref.label,
25
- forLabel = _ref.forLabel,
26
- hasError = _ref.hasError,
27
- required = _ref.required,
28
- errorMessage = _ref.errorMessage,
29
- props = (0, _objectWithoutPropertiesLoose2["default"])(_ref, _excluded);
30
- return (0, _jsxRuntime.jsxs)(_react["default"].Fragment, {
31
- children: [label && (0, _jsxRuntime.jsxs)(_.Label, {
32
- htmlFor: forLabel,
33
- children: [label, required && '*']
34
- }), (0, _jsxRuntime.jsx)("textarea", (0, _extends2["default"])({}, props, {
35
- ref: ref,
36
- sx: {
37
- border: '1px solid',
38
- borderColor: 'border',
39
- backgroundColor: 'card',
40
- borderRadius: 1,
41
- lineHeight: 'inherit',
42
- px: 3,
43
- py: 2,
44
- fontSize: 2,
45
- mb: 2,
46
- color: 'text',
47
- display: 'block',
48
- width: '100%',
49
- '&:focus': {
50
- borderColor: 'brand.60',
51
- outline: 'none'
52
- },
53
- '&:disabled': {
54
- backgroundColor: 'background'
55
- }
56
- }
57
- })), hasError && errorMessage && (0, _jsxRuntime.jsx)(_.Validation, {
58
- children: errorMessage
59
- })]
60
- });
22
+ /**
23
+ * Internal dependencies
24
+ */
25
+ var Textarea = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
26
+ return (0, _jsxRuntime.jsx)(_Input.Input, (0, _extends2["default"])({
27
+ ref: ref,
28
+ as: "textarea"
29
+ }, props));
61
30
  });
62
31
 
63
32
  exports.Textarea = Textarea;
64
- Textarea.propTypes = {
65
- variant: _propTypes["default"].string,
66
- label: _propTypes["default"].string,
67
- hasError: _propTypes["default"].bool,
68
- required: _propTypes["default"].bool,
69
- forLabel: _propTypes["default"].string,
70
- errorMessage: _propTypes["default"].string
71
- };
72
33
  Textarea.displayName = 'Textarea';
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports["default"] = exports.Default = void 0;
5
+
6
+ var Form = _interopRequireWildcard(require("../NewForm"));
7
+
8
+ var _jsxRuntime = require("theme-ui/jsx-runtime");
9
+
10
+ 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); }
11
+
12
+ 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; }
13
+
14
+ /** @jsxImportSource theme-ui */
15
+
16
+ /**
17
+ * Internal dependencies
18
+ */
19
+ var _default = {
20
+ title: 'Form/Textarea',
21
+ argTypes: {
22
+ placeholder: {
23
+ type: {
24
+ name: 'string',
25
+ required: false
26
+ },
27
+ control: {
28
+ type: 'text'
29
+ }
30
+ },
31
+ label: {
32
+ type: {
33
+ name: 'string',
34
+ required: false
35
+ },
36
+ control: {
37
+ type: 'text'
38
+ }
39
+ }
40
+ }
41
+ };
42
+ exports["default"] = _default;
43
+
44
+ var DefaultComponent = function DefaultComponent() {
45
+ return (0, _jsxRuntime.jsxs)(Form.Root, {
46
+ children: [(0, _jsxRuntime.jsx)(Form.Textarea, {
47
+ forLabel: "my-text-area",
48
+ rows: "5",
49
+ label: "Regular textarea"
50
+ }), (0, _jsxRuntime.jsx)("hr", {
51
+ sx: {
52
+ my: 4
53
+ }
54
+ }), (0, _jsxRuntime.jsx)(Form.Textarea, {
55
+ forLabel: "my-text-area-error",
56
+ rows: "5",
57
+ label: "Error textarea",
58
+ errorMessage: "Please type numeric characters only",
59
+ required: true,
60
+ hasError: true
61
+ })]
62
+ });
63
+ };
64
+
65
+ var Default = DefaultComponent.bind({});
66
+ exports.Default = Default;
67
+ Default.args = {};
@@ -13,30 +13,36 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
13
13
 
14
14
  var _md = require("react-icons/md");
15
15
 
16
- var _ = require("..");
17
-
18
16
  var _jsxRuntime = require("theme-ui/jsx-runtime");
19
17
 
20
- var _excluded = ["children", "isValid"];
18
+ var _excluded = ["children", "isValid", "describedId"];
21
19
 
20
+ /**
21
+ * Internal dependencies
22
+ */
22
23
  var Validation = function Validation(_ref) {
23
24
  var children = _ref.children,
24
25
  isValid = _ref.isValid,
26
+ _ref$describedId = _ref.describedId,
27
+ describedId = _ref$describedId === void 0 ? null : _ref$describedId,
25
28
  props = (0, _objectWithoutPropertiesLoose2["default"])(_ref, _excluded);
26
29
  var Icon = isValid ? _md.MdCheckCircle : _md.MdErrorOutline;
27
- return (0, _jsxRuntime.jsxs)(_.Heading, (0, _extends2["default"])({
28
- variant: "h5",
29
- as: "p",
30
+ var IconLabel = isValid ? 'Valid' : 'Invalid';
31
+ return (0, _jsxRuntime.jsxs)("p", (0, _extends2["default"])({
30
32
  sx: {
31
33
  color: isValid ? 'success' : 'error',
32
34
  display: 'flex',
33
- alignItems: 'center'
34
- }
35
+ alignItems: 'center',
36
+ m: 0,
37
+ fontSize: 1
38
+ },
39
+ id: describedId ? "describe-" + describedId + "-validation" : undefined
35
40
  }, props, {
36
41
  children: [(0, _jsxRuntime.jsx)(Icon, {
37
42
  sx: {
38
43
  mr: 1
39
- }
44
+ },
45
+ "aria-label": IconLabel
40
46
  }), children]
41
47
  }));
42
48
  };
@@ -44,5 +50,6 @@ var Validation = function Validation(_ref) {
44
50
  exports.Validation = Validation;
45
51
  Validation.propTypes = {
46
52
  children: _propTypes["default"].node,
47
- isValid: _propTypes["default"].bool
53
+ isValid: _propTypes["default"].bool,
54
+ describedId: _propTypes["default"].string
48
55
  };
@@ -15,7 +15,7 @@ var _jsxRuntime = require("theme-ui/jsx-runtime");
15
15
  * Internal dependencies
16
16
  */
17
17
  var _default = {
18
- title: 'NewConfirmationDialog',
18
+ title: 'Dialog/NewConfirmationDialog',
19
19
  component: _.NewConfirmationDialog
20
20
  };
21
21
  exports["default"] = _default;
@@ -32,7 +32,7 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
32
32
  * Internal dependencies
33
33
  */
34
34
  var _default = {
35
- title: 'NewDialog',
35
+ title: 'Dialog/NewDialog',
36
36
  component: NewDialog.Root
37
37
  };
38
38
  exports["default"] = _default;
@@ -7,8 +7,20 @@ var _FormSelect = require("./FormSelect");
7
7
 
8
8
  var _FormAutocomplete = require("./FormAutocomplete");
9
9
 
10
+ var _Textarea = require("../Form/Textarea");
11
+
12
+ exports.Textarea = _Textarea.Textarea;
13
+
14
+ var _Input = require("../Form/Input");
15
+
16
+ exports.Input = _Input.Input;
17
+
10
18
  var _Form = require("./Form");
11
19
 
20
+ var _Label = require("../Form/Label");
21
+
22
+ exports.Label = _Label.Label;
23
+
12
24
  /**
13
25
  * Internal dependencies
14
26
  */
@@ -11,7 +11,7 @@ var _jsxRuntime = require("theme-ui/jsx-runtime");
11
11
  * Internal dependencies
12
12
  */
13
13
  var _default = {
14
- title: 'NewTabs',
14
+ title: 'Tabs',
15
15
  component: _.NewTabs
16
16
  };
17
17
  exports["default"] = _default;
@@ -37,16 +37,22 @@ var Default = function Default() {
37
37
  })]
38
38
  }), (0, _jsxRuntime.jsx)(_.TabsContent, {
39
39
  value: "all",
40
- children: (0, _jsxRuntime.jsx)(_.Text, {
41
- children: "All content"
40
+ children: (0, _jsxRuntime.jsxs)(_.Text, {
41
+ children: ["All content ", (0, _jsxRuntime.jsx)("a", {
42
+ href: "https://google.com",
43
+ children: "https://google.com"
44
+ })]
42
45
  })
43
46
  }), (0, _jsxRuntime.jsx)(_.TabsContent, {
44
47
  value: "live",
45
48
  children: "Live content"
46
49
  }), (0, _jsxRuntime.jsx)(_.TabsContent, {
47
50
  value: "dev",
48
- children: (0, _jsxRuntime.jsx)(_.Text, {
49
- children: "In Development content"
51
+ children: (0, _jsxRuntime.jsxs)(_.Text, {
52
+ children: ["In Development content ", (0, _jsxRuntime.jsx)("button", {
53
+ type: "button",
54
+ children: "Hey I am a button"
55
+ }), ' ']
50
56
  })
51
57
  })]
52
58
  });
@@ -36,7 +36,7 @@ var TabsList = function TabsList(_ref) {
36
36
  borderColor: 'border',
37
37
  display: 'flex'
38
38
  }, sx),
39
- title: title,
39
+ "aria-label": title,
40
40
  children: children
41
41
  });
42
42
  };
@@ -11,7 +11,7 @@ var _jsxRuntime = require("theme-ui/jsx-runtime");
11
11
  * Internal dependencies
12
12
  */
13
13
  var _default = {
14
- title: 'Tabs',
14
+ title: 'Deprecated/Tabs',
15
15
  component: _.Tabs
16
16
  };
17
17
  exports["default"] = _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/vip-design-system",
3
- "version": "0.26.1",
3
+ "version": "0.26.2",
4
4
  "main": "build/system/index.js",
5
5
  "scripts": {
6
6
  "build-storybook": "build-storybook",
@@ -85,6 +85,7 @@ export const Trigger = React.forwardRef(
85
85
  '&[data-state="open"]': {
86
86
  backgroundColor: 'backgroundSecondary',
87
87
  borderBottom: theme => `1px solid ${ theme.colors.border }`,
88
+ '.vip-accordion-trigger-indicator': { transform: 'rotate(270deg)' },
88
89
  },
89
90
  '&:hover': { backgroundColor: 'backgroundSecondary' },
90
91
  } }
@@ -93,12 +94,12 @@ export const Trigger = React.forwardRef(
93
94
  >
94
95
  { children }
95
96
  <MdChevronRight
97
+ className="vip-accordion-trigger-indicator"
96
98
  sx={ {
97
99
  fontSize: 3,
98
100
  color: 'text',
99
101
  transform: 'rotate(90deg)',
100
102
  transition: 'transform 300ms cubic-bezier(0.87, 0, 0.13, 1)',
101
- '[data-state=open] &': { transform: 'rotate(270deg)' },
102
103
  } }
103
104
  aria-hidden
104
105
  />
@@ -0,0 +1,54 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { useState } from 'react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { Form } from '..';
10
+ import { Checkbox } from './Checkbox';
11
+ import { Label } from './Label';
12
+ import { Flex } from '../Flex';
13
+
14
+ export default {
15
+ title: 'Form/Checkbox',
16
+ component: Checkbox,
17
+ };
18
+
19
+ export const Default = () => {
20
+ const [ checked, setChecked ] = useState( true );
21
+ const [ checked2, setChecked2 ] = useState( false );
22
+
23
+ return (
24
+ <Form.Root>
25
+ <fieldset>
26
+ <legend>Tell me your prefereces</legend>
27
+
28
+ <Flex sx={ { alignItems: 'center' } }>
29
+ <Checkbox
30
+ id="check1"
31
+ checked={ checked }
32
+ aria-labelledby="label-check1"
33
+ onCheckedChange={ setChecked }
34
+ />
35
+ <Label sx={ { m: 0, ml: 2 } } htmlFor="check1" id="label-check1">
36
+ This option
37
+ </Label>
38
+ </Flex>
39
+
40
+ <Flex sx={ { alignItems: 'center' } }>
41
+ <Checkbox
42
+ id="check2"
43
+ checked={ checked2 }
44
+ aria-labelledby="label-check2"
45
+ onCheckedChange={ setChecked2 }
46
+ />
47
+ <Label sx={ { m: 0, ml: 2 } } htmlFor="check2" id="label-check2">
48
+ This option too
49
+ </Label>
50
+ </Flex>
51
+ </fieldset>
52
+ </Form.Root>
53
+ );
54
+ };
@@ -10,45 +10,61 @@ import PropTypes from 'prop-types';
10
10
  * Internal dependencies
11
11
  */
12
12
  import { Validation, Label } from '../';
13
+ import { Input as ThemeInput } from 'theme-ui';
14
+
15
+ const RequiredLabel = () => (
16
+ <span sx={ { color: 'error', display: 'inline-block', ml: 2, fontSize: 1 } }>(Required)</span>
17
+ );
18
+
19
+ const inputStyles = {
20
+ unset: 'all',
21
+ border: '1px solid',
22
+ borderColor: 'border',
23
+ backgroundColor: 'card',
24
+ borderRadius: 1,
25
+ lineHeight: 'inherit',
26
+ px: 3,
27
+ py: 2,
28
+ fontSize: 2,
29
+ mb: 2,
30
+ color: 'text',
31
+ display: 'block',
32
+ width: '100%',
33
+ '&:focus': theme => theme.outline,
34
+ '&:focus-visible': theme => theme.outline,
35
+ '&:disabled': {
36
+ bg: 'backgroundSecondary',
37
+ },
38
+ '&::placeholder': {
39
+ color: 'placeholder',
40
+ },
41
+ };
13
42
 
14
43
  const Input = React.forwardRef(
15
- ( { variant, label, forLabel, hasError, required, errorMessage, ...props }, ref ) => (
44
+ ( { variant, label, forLabel, hasError, required, sx = {}, errorMessage, ...props }, ref ) => (
16
45
  <React.Fragment>
17
46
  { label && (
18
47
  <Label htmlFor={ forLabel }>
19
48
  { label }
20
- { required && '*' }
49
+ { required && <RequiredLabel /> }
21
50
  </Label>
22
51
  ) }
23
- <input
24
- { ...props }
52
+
53
+ <ThemeInput
25
54
  ref={ ref }
26
55
  id={ forLabel }
27
56
  required={ required }
28
- sx={ {
29
- border: '1px solid',
30
- borderColor: 'border',
31
- backgroundColor: 'card',
32
- borderRadius: 1,
33
- lineHeight: 'inherit',
34
- px: 3,
35
- py: 2,
36
- fontSize: 2,
37
- mb: 2,
38
- color: 'text',
39
- display: 'block',
40
- width: '100%',
41
- '&:focus': theme => theme.outline,
42
- '&:focus-visible': theme => theme.outline,
43
- '&:disabled': {
44
- bg: 'backgroundSecondary',
45
- },
46
- '&::placeholder': {
47
- color: 'placeholder',
48
- },
49
- } }
57
+ noValidate
58
+ aria-describedby={ hasError ? `describe-${ forLabel }-validation` : undefined }
59
+ sx={ { ...inputStyles, ...sx } }
60
+ { ...props }
50
61
  />
51
- { hasError && errorMessage && <Validation>{ errorMessage }</Validation> }
62
+
63
+ { hasError && errorMessage && (
64
+ <Validation isValid={ false } describedId={ forLabel }>
65
+ { errorMessage }
66
+ </Validation>
67
+ ) }
52
68
  </React.Fragment>
53
69
  )
54
70
  );
@@ -60,6 +76,7 @@ Input.propTypes = {
60
76
  required: PropTypes.bool,
61
77
  forLabel: PropTypes.string,
62
78
  errorMessage: PropTypes.string,
79
+ sx: PropTypes.object,
63
80
  };
64
81
 
65
82
  Input.displayName = 'Input';
@@ -3,11 +3,36 @@
3
3
  /**
4
4
  * Internal dependencies
5
5
  */
6
- import { Input } from '..';
6
+ import { Form } from '..';
7
7
 
8
8
  export default {
9
- title: 'Input',
10
- component: Input,
9
+ title: 'Form/Input',
11
10
  };
12
11
 
13
- export const Default = () => <Input placeholder="Your input here..." />;
12
+ export const Default = () => (
13
+ <Form.Root>
14
+ <Form.Input
15
+ placeholder="Your input here..."
16
+ label="Always add a label to inputs"
17
+ forLabel="input-simple"
18
+ />
19
+
20
+ <hr sx={ { my: 4 } } />
21
+
22
+ <Form.Input
23
+ forLabel="input-with-error"
24
+ label="Error Input"
25
+ errorMessage="Please type numeric characters only"
26
+ hasError
27
+ />
28
+
29
+ <hr sx={ { my: 4 } } />
30
+
31
+ <Form.Input forLabel="input-with-required" label="Required" required />
32
+
33
+ <hr sx={ { my: 4 } } />
34
+
35
+ <Form.Label htmlFor="input-with-custom-label">Custom Label outside the Input</Form.Label>
36
+ <Form.Input forLabel="input-with-custom-label" required />
37
+ </Form.Root>
38
+ );
@@ -0,0 +1,66 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { useState } from 'react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { Form } from '..';
10
+ import { Radio } from './Radio';
11
+ import { Label } from './Label';
12
+ import { Flex } from '../Flex';
13
+
14
+ export default {
15
+ title: 'Form/Radio',
16
+ component: Radio,
17
+ };
18
+
19
+ export const Default = () => {
20
+ const [ checked, setChecked ] = useState( 'a' );
21
+
22
+ return (
23
+ <Form.Root>
24
+ <p>
25
+ Per recommendation, if you have a Radio button, use a Fieldset with a legend as wrapper to
26
+ your options.{ ' ' }
27
+ <a href="https://a11y-collective.github.io/demos/en/accessible-code/form-fieldsets.html">
28
+ Reference to Form fieldsets
29
+ </a>
30
+ </p>
31
+ <fieldset>
32
+ <legend sx={ { mb: 0, fontSize: 2, fontWeight: 'bold' } }>
33
+ Apply the policy to these domains
34
+ </legend>
35
+
36
+ <Flex sx={ { alignItems: 'center' } }>
37
+ <Radio
38
+ name="includeSubdomains"
39
+ id="include-all-domains-opt"
40
+ onChange={ () => setChecked( 'a' ) }
41
+ value={ 'a' }
42
+ checked={ checked === 'a' }
43
+ />
44
+
45
+ <Label htmlFor="include-all-domains-opt" sx={ { mb: 0 } }>
46
+ All domains listed on this environment, and all subdomains
47
+ </Label>
48
+ </Flex>
49
+
50
+ <Flex sx={ { alignItems: 'center', mb: 1 } }>
51
+ <Radio
52
+ name="includeSubdomains"
53
+ id="include-subdomains-opt"
54
+ onChange={ () => setChecked( 'b' ) }
55
+ checked={ checked === 'b' }
56
+ value={ 'b' }
57
+ />
58
+
59
+ <Label id="exclude-subdomains" htmlFor="include-subdomains-opt" sx={ { mb: 0 } }>
60
+ All domains listed on this environment
61
+ </Label>
62
+ </Flex>
63
+ </fieldset>
64
+ </Form.Root>
65
+ );
66
+ };
@@ -9,7 +9,7 @@ import { useState } from 'react';
9
9
  import { Box, Dialog, DialogMenu, DialogMenuItem, DialogDivider, Select, Button } from '..';
10
10
 
11
11
  export default {
12
- title: 'Select',
12
+ title: 'Deprecated/Select',
13
13
  component: Dialog,
14
14
  };
15
15
 
@@ -4,60 +4,15 @@
4
4
  * External dependencies
5
5
  */
6
6
  import React from 'react';
7
- import PropTypes from 'prop-types';
8
7
 
9
8
  /**
10
9
  * Internal dependencies
11
10
  */
12
- import { Validation, Label } from '../';
11
+ import { Input } from './Input';
13
12
 
14
- const Textarea = React.forwardRef(
15
- ( { variant, label, forLabel, hasError, required, errorMessage, ...props }, ref ) => (
16
- <React.Fragment>
17
- { label && (
18
- <Label htmlFor={ forLabel }>
19
- { label }
20
- { required && '*' }
21
- </Label>
22
- ) }
23
- <textarea
24
- { ...props }
25
- ref={ ref }
26
- sx={ {
27
- border: '1px solid',
28
- borderColor: 'border',
29
- backgroundColor: 'card',
30
- borderRadius: 1,
31
- lineHeight: 'inherit',
32
- px: 3,
33
- py: 2,
34
- fontSize: 2,
35
- mb: 2,
36
- color: 'text',
37
- display: 'block',
38
- width: '100%',
39
- '&:focus': {
40
- borderColor: 'brand.60',
41
- outline: 'none',
42
- },
43
- '&:disabled': {
44
- backgroundColor: 'background',
45
- },
46
- } }
47
- />
48
- { hasError && errorMessage && <Validation>{ errorMessage }</Validation> }
49
- </React.Fragment>
50
- )
51
- );
52
-
53
- Textarea.propTypes = {
54
- variant: PropTypes.string,
55
- label: PropTypes.string,
56
- hasError: PropTypes.bool,
57
- required: PropTypes.bool,
58
- forLabel: PropTypes.string,
59
- errorMessage: PropTypes.string,
60
- };
13
+ const Textarea = React.forwardRef( ( props, ref ) => (
14
+ <Input ref={ ref } as="textarea" { ...props } />
15
+ ) );
61
16
 
62
17
  Textarea.displayName = 'Textarea';
63
18
 
@@ -0,0 +1,40 @@
1
+ /** @jsxImportSource theme-ui */
2
+
3
+ /**
4
+ * Internal dependencies
5
+ */
6
+ import * as Form from '../NewForm';
7
+
8
+ export default {
9
+ title: 'Form/Textarea',
10
+ argTypes: {
11
+ placeholder: {
12
+ type: { name: 'string', required: false },
13
+ control: { type: 'text' },
14
+ },
15
+ label: {
16
+ type: { name: 'string', required: false },
17
+ control: { type: 'text' },
18
+ },
19
+ },
20
+ };
21
+
22
+ const DefaultComponent = () => (
23
+ <Form.Root>
24
+ <Form.Textarea forLabel="my-text-area" rows="5" label="Regular textarea" />
25
+
26
+ <hr sx={ { my: 4 } } />
27
+
28
+ <Form.Textarea
29
+ forLabel="my-text-area-error"
30
+ rows="5"
31
+ label="Error textarea"
32
+ errorMessage="Please type numeric characters only"
33
+ required
34
+ hasError
35
+ />
36
+ </Form.Root>
37
+ );
38
+
39
+ export const Default = DefaultComponent.bind( {} );
40
+ Default.args = {};
@@ -9,27 +9,33 @@ import { MdErrorOutline, MdCheckCircle } from 'react-icons/md';
9
9
  /**
10
10
  * Internal dependencies
11
11
  */
12
- import { Heading } from '..';
13
12
 
14
- const Validation = ( { children, isValid, ...props } ) => {
13
+ const Validation = ( { children, isValid, describedId = null, ...props } ) => {
15
14
  const Icon = isValid ? MdCheckCircle : MdErrorOutline;
15
+ const IconLabel = isValid ? 'Valid' : 'Invalid';
16
16
 
17
17
  return (
18
- <Heading
19
- variant="h5"
20
- as="p"
21
- sx={ { color: isValid ? 'success' : 'error', display: 'flex', alignItems: 'center' } }
18
+ <p
19
+ sx={ {
20
+ color: isValid ? 'success' : 'error',
21
+ display: 'flex',
22
+ alignItems: 'center',
23
+ m: 0,
24
+ fontSize: 1,
25
+ } }
26
+ id={ describedId ? `describe-${ describedId }-validation` : undefined }
22
27
  { ...props }
23
28
  >
24
- <Icon sx={ { mr: 1 } } />
29
+ <Icon sx={ { mr: 1 } } aria-label={ IconLabel } />
25
30
  { children }
26
- </Heading>
31
+ </p>
27
32
  );
28
33
  };
29
34
 
30
35
  Validation.propTypes = {
31
36
  children: PropTypes.node,
32
37
  isValid: PropTypes.bool,
38
+ describedId: PropTypes.string,
33
39
  };
34
40
 
35
41
  export { Validation };
@@ -5,7 +5,7 @@ import React from 'react';
5
5
  import { Box, NewConfirmationDialog, Button } from '..';
6
6
 
7
7
  export default {
8
- title: 'NewConfirmationDialog',
8
+ title: 'Dialog/NewConfirmationDialog',
9
9
  component: NewConfirmationDialog,
10
10
  };
11
11
 
@@ -14,7 +14,7 @@ import ScreenReaderText from '../ScreenReaderText';
14
14
  import * as NewDialog from '.';
15
15
 
16
16
  export default {
17
- title: 'NewDialog',
17
+ title: 'Dialog/NewDialog',
18
18
  component: NewDialog.Root,
19
19
  };
20
20
 
@@ -4,12 +4,15 @@
4
4
 
5
5
  import { FormSelect } from './FormSelect';
6
6
  import { FormAutocomplete } from './FormAutocomplete';
7
+ import { Textarea } from '../Form/Textarea';
8
+ import { Input } from '../Form/Input';
7
9
  import { Form } from './Form';
10
+ import { Label } from '../Form/Label';
8
11
 
9
12
  const Select = FormSelect;
10
13
  const Autocomplete = FormAutocomplete;
11
14
  const Root = Form;
12
15
 
13
- export { Root, Select, Autocomplete };
16
+ export { Root, Select, Autocomplete, Textarea, Input, Label };
14
17
 
15
18
  export default Root;
@@ -4,7 +4,7 @@
4
4
  import { NewTabs, TabsTrigger, TabsList, TabsContent, Text } from '..';
5
5
 
6
6
  export default {
7
- title: 'NewTabs',
7
+ title: 'Tabs',
8
8
  component: NewTabs,
9
9
  };
10
10
 
@@ -19,11 +19,15 @@ export const Default = () => (
19
19
  </TabsTrigger>
20
20
  </TabsList>
21
21
  <TabsContent value="all">
22
- <Text>All content</Text>
22
+ <Text>
23
+ All content <a href="https://google.com">https://google.com</a>
24
+ </Text>
23
25
  </TabsContent>
24
26
  <TabsContent value="live">Live content</TabsContent>
25
27
  <TabsContent value="dev">
26
- <Text>In Development content</Text>
28
+ <Text>
29
+ In Development content <button type="button">Hey I am a button</button>{ ' ' }
30
+ </Text>
27
31
  </TabsContent>
28
32
  </NewTabs>
29
33
  );
@@ -18,7 +18,7 @@ const TabsList = ( { children, title, sx } ) => (
18
18
  display: 'flex',
19
19
  ...sx,
20
20
  } }
21
- title={ title }
21
+ aria-label={ title }
22
22
  >
23
23
  { children }
24
24
  </TabsPrimitive.List>
@@ -4,7 +4,7 @@
4
4
  import { Tabs, TabItem } from '..';
5
5
 
6
6
  export default {
7
- title: 'Tabs',
7
+ title: 'Deprecated/Tabs',
8
8
  component: Tabs,
9
9
  };
10
10