@automattic/vip-design-system 0.11.1 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,5 +5,6 @@ module.exports = {
5
5
  '@storybook/addon-docs',
6
6
  '@storybook/addon-essentials',
7
7
  '@storybook/addon-links',
8
+ '@storybook/addon-controls',
8
9
  ],
9
10
  };
@@ -11,5 +11,6 @@ export const decorators = [ withBoundingBox, withColorMode, withThemeProvider ];
11
11
 
12
12
  export const parameters = {
13
13
  actions: { argTypesRegex: '^on[A-Z].*' },
14
+ controls: { expanded: true },
14
15
  backgrounds,
15
16
  };
@@ -13,91 +13,64 @@ var _classnames = _interopRequireDefault(require("classnames"));
13
13
 
14
14
  var _propTypes = _interopRequireDefault(require("prop-types"));
15
15
 
16
+ var Switch = _interopRequireWildcard(require("@radix-ui/react-switch"));
17
+
16
18
  var _jsxRuntime = require("theme-ui/jsx-runtime");
17
19
 
18
- var _excluded = ["name", "className"];
20
+ var _excluded = ["name", "onChange", "className"];
21
+
22
+ 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); }
23
+
24
+ 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; }
19
25
 
26
+ // Documentation for Radix Switch component
27
+ // https://www.radix-ui.com/docs/primitives/components/switch
20
28
  var Toggle = function Toggle(_ref) {
21
29
  var _ref$name = _ref.name,
22
30
  name = _ref$name === void 0 ? 'toggle' : _ref$name,
31
+ onChange = _ref.onChange,
23
32
  _ref$className = _ref.className,
24
33
  className = _ref$className === void 0 ? null : _ref$className,
25
- props = (0, _objectWithoutPropertiesLoose2["default"])(_ref, _excluded);
26
- return (0, _jsxRuntime.jsxs)(CheckBoxWrapper, {
27
- className: (0, _classnames["default"])('vip-checkbox-component', className),
28
- children: [(0, _jsxRuntime.jsx)(CheckBox, (0, _extends2["default"])({
29
- name: name,
30
- id: name,
31
- type: "checkbox"
32
- }, props)), (0, _jsxRuntime.jsx)(CheckBoxLabel, {
33
- htmlFor: name
34
- })]
35
- });
36
- };
37
-
38
- exports.Toggle = Toggle;
39
- Toggle.propTypes = {
40
- name: _propTypes["default"].string,
41
- className: _propTypes["default"].any
42
- };
43
-
44
- var CheckBoxWrapper = function CheckBoxWrapper(props) {
45
- return (0, _jsxRuntime.jsx)("div", (0, _extends2["default"])({
46
- sx: {
47
- position: 'relative'
48
- }
49
- }, props));
50
- };
51
-
52
- var CheckBoxLabel = function CheckBoxLabel(props) {
53
- return (0, _jsxRuntime.jsx)("label", (0, _extends2["default"])({
34
+ rest = (0, _objectWithoutPropertiesLoose2["default"])(_ref, _excluded);
35
+ return (0, _jsxRuntime.jsx)(Switch.Root, (0, _extends2["default"])({
36
+ className: (0, _classnames["default"])('vip-toggle-component', className),
54
37
  sx: {
55
- position: 'absolute',
56
- top: '0',
57
- left: '0',
58
- width: '42px',
59
- height: '24px',
60
- borderRadius: '15px',
38
+ all: 'unset',
39
+ width: 42,
40
+ height: 24,
61
41
  backgroundColor: 'muted',
62
- cursor: 'pointer',
63
- '&::after': {
64
- content: "''",
42
+ borderRadius: '15px',
43
+ position: 'relative',
44
+ WebkitTapHighlightColor: 'rgba(0, 0, 0, 0)',
45
+ '&[data-state="checked"]': {
46
+ backgroundColor: 'success'
47
+ }
48
+ },
49
+ name: name,
50
+ onCheckedChange: onChange || undefined
51
+ }, rest, {
52
+ children: (0, _jsxRuntime.jsx)(Switch.Thumb, {
53
+ sx: {
65
54
  display: 'block',
55
+ width: 18,
56
+ height: 18,
57
+ backgroundColor: 'white',
66
58
  borderRadius: '50%',
67
- width: '18px',
68
- height: '18px',
69
- margin: '3px',
70
- backgroundColor: 'card',
71
- boxShadow: 'low',
72
- transition: '0.2s'
59
+ boxShadow: 'rgb(0 0 0 / 5%) 0px 1px 5px, rgb(0 0 0 / 15%) 0px 1px 1px',
60
+ transition: 'transform 100ms',
61
+ transform: 'translateX(3px)',
62
+ willChange: 'transform',
63
+ '&[data-state="checked"]': {
64
+ transform: 'translateX(21px)'
65
+ }
73
66
  }
74
- }
75
- }, props));
67
+ })
68
+ }));
76
69
  };
77
70
 
78
- var CheckBox = function CheckBox(props) {
79
- return (0, _jsxRuntime.jsx)("input", (0, _extends2["default"])({
80
- sx: {
81
- opacity: '0',
82
- zIndex: '1',
83
- borderRadius: '15px',
84
- width: '42px',
85
- height: '24px',
86
- padding: 0,
87
- margin: 0,
88
- display: 'block',
89
- '&:checked + label': {
90
- backgroundColor: 'success',
91
- '&::after': {
92
- content: "''",
93
- display: 'block',
94
- borderRadius: '50%',
95
- width: '18px',
96
- height: '18px',
97
- marginLeft: '21px',
98
- transition: '0.2s'
99
- }
100
- }
101
- }
102
- }, props));
71
+ exports.Toggle = Toggle;
72
+ Toggle.propTypes = {
73
+ name: _propTypes["default"].string,
74
+ className: _propTypes["default"].any,
75
+ onChange: _propTypes["default"].func
103
76
  };
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports["default"] = exports.Primary = exports.ExternalLabel = void 0;
5
+
6
+ var _ = require("..");
7
+
8
+ var _jsxRuntime = require("theme-ui/jsx-runtime");
9
+
10
+ /**
11
+ * External dependencies
12
+ */
13
+
14
+ /**
15
+ * Internal dependencies
16
+ */
17
+ var _default = {
18
+ title: 'Toggle',
19
+ component: _.Toggle,
20
+ argTypes: {
21
+ checked: {
22
+ options: [true, false],
23
+ "default": true,
24
+ control: {
25
+ type: 'radio'
26
+ }
27
+ }
28
+ }
29
+ };
30
+ exports["default"] = _default;
31
+
32
+ var Default = function Default(args) {
33
+ return (0, _jsxRuntime.jsx)("form", {
34
+ children: (0, _jsxRuntime.jsx)(_.Toggle, {
35
+ defaultChecked: true,
36
+ checked: args.checked,
37
+ "aria-label": "Feature flag"
38
+ })
39
+ });
40
+ };
41
+
42
+ var WithLabel = function WithLabel(args) {
43
+ return (0, _jsxRuntime.jsxs)("form", {
44
+ children: [(0, _jsxRuntime.jsx)(_.Label, {
45
+ htmlFor: "custom-label-input",
46
+ children: "Custom Label here"
47
+ }), (0, _jsxRuntime.jsx)(_.Toggle, {
48
+ id: "custom-label-input",
49
+ defaultChecked: true,
50
+ checked: args.checked,
51
+ "aria-label": "Feature flag"
52
+ })]
53
+ });
54
+ };
55
+
56
+ var Primary = Default.bind({
57
+ checked: true
58
+ });
59
+ exports.Primary = Primary;
60
+ var ExternalLabel = WithLabel.bind({
61
+ checked: true
62
+ });
63
+ exports.ExternalLabel = ExternalLabel;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
6
+
7
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
8
+
9
+ var _react = require("@testing-library/react");
10
+
11
+ var _jestAxe = require("jest-axe");
12
+
13
+ var _Toggle = require("./Toggle");
14
+
15
+ var _jsxRuntime = require("theme-ui/jsx-runtime");
16
+
17
+ /**
18
+ * External dependencies
19
+ */
20
+
21
+ /**
22
+ * Internal dependencies
23
+ */
24
+ describe('<Toggle />', function () {
25
+ it('renders the Toggle component', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() {
26
+ var _render, container;
27
+
28
+ return _regenerator["default"].wrap(function _callee$(_context) {
29
+ while (1) {
30
+ switch (_context.prev = _context.next) {
31
+ case 0:
32
+ _render = (0, _react.render)((0, _jsxRuntime.jsx)(_Toggle.Toggle, {
33
+ "aria-label": "Dinner room Light",
34
+ defaultChecked: true,
35
+ name: "my-toggle"
36
+ })), container = _render.container;
37
+ expect(_react.screen.getByRole('switch')).toBeInTheDocument(); // Check for accessibility issues
38
+
39
+ _context.t0 = expect;
40
+ _context.next = 5;
41
+ return (0, _jestAxe.axe)(container);
42
+
43
+ case 5:
44
+ _context.t1 = _context.sent;
45
+ _context.next = 8;
46
+ return (0, _context.t0)(_context.t1).toHaveNoViolations();
47
+
48
+ case 8:
49
+ case "end":
50
+ return _context.stop();
51
+ }
52
+ }
53
+ }, _callee);
54
+ })));
55
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/vip-design-system",
3
- "version": "0.11.1",
3
+ "version": "0.12.0",
4
4
  "main": "build/system/index.js",
5
5
  "scripts": {
6
6
  "build-storybook": "build-storybook",
@@ -19,6 +19,7 @@
19
19
  "dependencies": {
20
20
  "@radix-ui/react-checkbox": "^0.1.0",
21
21
  "@radix-ui/react-radio-group": "^0.1.0",
22
+ "@radix-ui/react-switch": "^0.1.5",
22
23
  "@radix-ui/react-tooltip": "^0.1.0",
23
24
  "babel-loader": "^8.2.2",
24
25
  "classnames": "^2.3.1",
@@ -83,6 +84,7 @@
83
84
  "@mdx-js/react": "^2.1.1",
84
85
  "@storybook/addon-a11y": "^6.5.9",
85
86
  "@storybook/addon-actions": "^6.5.9",
87
+ "@storybook/addon-controls": "^6.5.9",
86
88
  "@storybook/addon-essentials": "^6.5.9",
87
89
  "@storybook/addon-links": "^6.5.9",
88
90
  "@storybook/react": "^6.5.9",
@@ -6,73 +6,47 @@
6
6
  import classNames from 'classnames';
7
7
  import PropTypes from 'prop-types';
8
8
 
9
- const Toggle = ( { name = 'toggle', className = null, ...props } ) => (
10
- <CheckBoxWrapper className={ classNames( 'vip-checkbox-component', className ) }>
11
- <CheckBox name={ name } id={ name } type="checkbox" { ...props } />
12
- <CheckBoxLabel htmlFor={ name } />
13
- </CheckBoxWrapper>
14
- );
15
-
16
- Toggle.propTypes = {
17
- name: PropTypes.string,
18
- className: PropTypes.any,
19
- };
20
-
21
- export { Toggle };
9
+ import * as Switch from '@radix-ui/react-switch';
22
10
 
23
- const CheckBoxWrapper = props => <div sx={ { position: 'relative' } } { ...props } />;
11
+ // Documentation for Radix Switch component
12
+ // https://www.radix-ui.com/docs/primitives/components/switch
24
13
 
25
- const CheckBoxLabel = props => (
26
- <label
14
+ export const Toggle = ( { name = 'toggle', onChange, className = null, ...rest } ) => (
15
+ <Switch.Root
16
+ className={ classNames( 'vip-toggle-component', className ) }
27
17
  sx={ {
28
- position: 'absolute',
29
- top: '0',
30
- left: '0',
31
- width: '42px',
32
- height: '24px',
33
- borderRadius: '15px',
18
+ all: 'unset',
19
+ width: 42,
20
+ height: 24,
34
21
  backgroundColor: 'muted',
35
- cursor: 'pointer',
36
- '&::after': {
37
- content: "''",
22
+ borderRadius: '15px',
23
+ position: 'relative',
24
+ WebkitTapHighlightColor: 'rgba(0, 0, 0, 0)',
25
+ '&[data-state="checked"]': { backgroundColor: 'success' },
26
+ } }
27
+ name={ name }
28
+ onCheckedChange={ onChange || undefined }
29
+ { ...rest }
30
+ >
31
+ <Switch.Thumb
32
+ sx={ {
38
33
  display: 'block',
34
+ width: 18,
35
+ height: 18,
36
+ backgroundColor: 'white',
39
37
  borderRadius: '50%',
40
- width: '18px',
41
- height: '18px',
42
- margin: '3px',
43
- backgroundColor: 'card',
44
- boxShadow: 'low',
45
- transition: '0.2s',
46
- },
47
- } }
48
- { ...props }
49
- />
38
+ boxShadow: 'rgb(0 0 0 / 5%) 0px 1px 5px, rgb(0 0 0 / 15%) 0px 1px 1px',
39
+ transition: 'transform 100ms',
40
+ transform: 'translateX(3px)',
41
+ willChange: 'transform',
42
+ '&[data-state="checked"]': { transform: 'translateX(21px)' },
43
+ } }
44
+ />
45
+ </Switch.Root>
50
46
  );
51
47
 
52
- const CheckBox = props => (
53
- <input
54
- sx={ {
55
- opacity: '0',
56
- zIndex: '1',
57
- borderRadius: '15px',
58
- width: '42px',
59
- height: '24px',
60
- padding: 0,
61
- margin: 0,
62
- display: 'block',
63
- '&:checked + label': {
64
- backgroundColor: 'success',
65
- '&::after': {
66
- content: "''",
67
- display: 'block',
68
- borderRadius: '50%',
69
- width: '18px',
70
- height: '18px',
71
- marginLeft: '21px',
72
- transition: '0.2s',
73
- },
74
- },
75
- } }
76
- { ...props }
77
- />
78
- );
48
+ Toggle.propTypes = {
49
+ name: PropTypes.string,
50
+ className: PropTypes.any,
51
+ onChange: PropTypes.func,
52
+ };
@@ -0,0 +1,42 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+
5
+ /**
6
+ * Internal dependencies
7
+ */
8
+ import { Toggle, Label } from '..';
9
+
10
+ export default {
11
+ title: 'Toggle',
12
+ component: Toggle,
13
+ argTypes: {
14
+ checked: {
15
+ options: [ true, false ],
16
+ default: true,
17
+ control: { type: 'radio' },
18
+ },
19
+ },
20
+ };
21
+
22
+ const Default = args => (
23
+ <form>
24
+ <Toggle defaultChecked checked={ args.checked } aria-label="Feature flag" />
25
+ </form>
26
+ );
27
+
28
+ const WithLabel = args => (
29
+ <form>
30
+ <Label htmlFor="custom-label-input">Custom Label here</Label>
31
+
32
+ <Toggle
33
+ id="custom-label-input"
34
+ defaultChecked
35
+ checked={ args.checked }
36
+ aria-label="Feature flag"
37
+ />
38
+ </form>
39
+ );
40
+
41
+ export const Primary = Default.bind( { checked: true } );
42
+ export const ExternalLabel = WithLabel.bind( { checked: true } );
@@ -0,0 +1,23 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { render, screen } from '@testing-library/react';
5
+ import { axe } from 'jest-axe';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { Toggle } from './Toggle';
11
+
12
+ describe( '<Toggle />', () => {
13
+ it( 'renders the Toggle component', async () => {
14
+ const { container } = render(
15
+ <Toggle aria-label="Dinner room Light" defaultChecked name="my-toggle" />
16
+ );
17
+
18
+ expect( screen.getByRole( 'switch' ) ).toBeInTheDocument();
19
+
20
+ // Check for accessibility issues
21
+ await expect( await axe( container ) ).toHaveNoViolations();
22
+ } );
23
+ } );
@@ -1,38 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.MultiSelect = void 0;
5
-
6
- var _reactSelect = _interopRequireDefault(require("react-select"));
7
-
8
- var _jsxRuntime = require("theme-ui/jsx-runtime");
9
-
10
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
11
-
12
- function _extends() { _extends = Object.assign || 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); }
13
-
14
- var vipGold = '#c29c69'; // hardcoding for now
15
-
16
- var vipGrey2 = '#d7dee2';
17
- var customStyles = {
18
- control: function control(styles) {
19
- return _extends({}, styles, {
20
- border: "1px solid " + vipGrey2,
21
- boxShadow: 'none',
22
- '&:hover': {
23
- border: "1px solid " + vipGold
24
- },
25
- '&:focus': {
26
- border: "1px solid " + vipGold
27
- }
28
- });
29
- }
30
- };
31
-
32
- var MultiSelect = function MultiSelect(props) {
33
- return (0, _jsxRuntime.jsx)(_reactSelect["default"], _extends({}, props, {
34
- styles: customStyles
35
- }));
36
- };
37
-
38
- exports.MultiSelect = MultiSelect;
@@ -1,60 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.UsageChart = void 0;
5
-
6
- var _framerMotion = require("framer-motion");
7
-
8
- var _propTypes = _interopRequireDefault(require("prop-types"));
9
-
10
- var _jsxRuntime = require("theme-ui/jsx-runtime");
11
-
12
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
13
-
14
- /**
15
- * External dependencies
16
- */
17
- var UsageChart = function UsageChart(_ref) {
18
- var total = _ref.total,
19
- max = _ref.max,
20
- _ref$variant = _ref.variant,
21
- variant = _ref$variant === void 0 ? 'primary' : _ref$variant;
22
- var width = total / max * 100 + '%';
23
- var formattedTotal = total;
24
-
25
- if (total > 1000000) {
26
- formattedTotal = (total / 1000000).toFixed(2) + "M";
27
- } else if (total > 1000) {
28
- formattedTotal = (total / 1000).toFixed(2) + "K";
29
- }
30
-
31
- return (0, _jsxRuntime.jsx)("div", {
32
- sx: {
33
- height: variant === 'primary' ? 32 : 8,
34
- overflow: 'hidden',
35
- backgroundColor: variant === 'primary' ? 'border' : 'transparent'
36
- },
37
- children: (0, _jsxRuntime.jsx)(_framerMotion.motion.div, {
38
- initial: {
39
- width: 0
40
- },
41
- animate: {
42
- width: width
43
- },
44
- transition: {
45
- duration: 0.7
46
- },
47
- sx: {
48
- height: '100%',
49
- backgroundColor: variant === 'primary' ? 'primary' : 'grey.40'
50
- }
51
- })
52
- });
53
- };
54
-
55
- exports.UsageChart = UsageChart;
56
- UsageChart.propTypes = {
57
- total: _propTypes["default"].number,
58
- max: _propTypes["default"].number,
59
- variant: _propTypes["default"].string
60
- };
@@ -1,7 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
-
5
- var _UsageChart = require("./UsageChart");
6
-
7
- exports.UsageChart = _UsageChart.UsageChart;