@automattic/vip-design-system 2.15.2 → 2.15.3

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.
@@ -7,16 +7,17 @@ import Autocomplete from 'accessible-autocomplete/react';
7
7
  import classNames from 'classnames';
8
8
  import PropTypes from 'prop-types';
9
9
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
10
- import { MdClose } from 'react-icons/md';
11
10
 
12
11
  /**
13
12
  * Internal dependencies
14
13
  */
14
+ import { FormAutocompleteMultiselectBadge } from './FormAutocompleteMultiselectBadge';
15
+ import { FormAutocompleteMultiselectButton } from './FormAutocompleteMultiselectButton';
15
16
  import { FormSelectArrow } from './FormSelectArrow';
16
17
  import { FormSelectContent } from './FormSelectContent';
17
18
  import { FormSelectLoading } from './FormSelectLoading';
18
19
  import { FormSelectSearch } from './FormSelectSearch';
19
- import { Button, Flex } from '../';
20
+ import { Flex } from '../';
20
21
  import { Validation } from '../Form';
21
22
  import { baseControlBorderStyle, inputBaseText } from '../Form/Input.styles';
22
23
  import { Label } from '../Form/Label';
@@ -126,42 +127,6 @@ AddSelectionStatus.propTypes = {
126
127
  status: PropTypes.string.isRequired,
127
128
  };
128
129
 
129
- const SelectedOptions = ( { index, option, unselectValue } ) => {
130
- return (
131
- <div key={ index } sx={ { mr: 1, maxWidth: '100%' } }>
132
- <Button
133
- variant="tertiary"
134
- onClick={ e => {
135
- e.preventDefault();
136
- unselectValue( option, index );
137
- } }
138
- sx={ {
139
- mt: 1,
140
- fontSize: 1,
141
- maxWidth: '100%',
142
- } }
143
- >
144
- <div
145
- sx={ {
146
- overflow: 'hidden',
147
- textOverflow: 'ellipsis',
148
- whiteSpace: 'nowrap',
149
- } }
150
- >
151
- { option }
152
- </div>
153
- <MdClose sx={ { ml: 2 } } />
154
- </Button>
155
- </div>
156
- );
157
- };
158
-
159
- SelectedOptions.propTypes = {
160
- index: PropTypes.number.isRequired,
161
- option: PropTypes.string.isRequired,
162
- unselectValue: PropTypes.func.isRequired,
163
- };
164
-
165
130
  const FormAutocompleteMultiselect = React.forwardRef(
166
131
  (
167
132
  {
@@ -188,6 +153,7 @@ const FormAutocompleteMultiselect = React.forwardRef(
188
153
  showAllValues = false,
189
154
  source,
190
155
  value,
156
+ listType = 'button',
191
157
  ...props
192
158
  },
193
159
  forwardRef
@@ -197,6 +163,8 @@ const FormAutocompleteMultiselect = React.forwardRef(
197
163
  REMOVE: 'remove',
198
164
  NONE: 'none',
199
165
  };
166
+ const ListComponent =
167
+ listType === 'button' ? FormAutocompleteMultiselectButton : FormAutocompleteMultiselectBadge;
200
168
  const [ isDirty, setIsDirty ] = useState( false );
201
169
  const [ selectedOptions, setSelectedOptions ] = useState( [] );
202
170
  const [ addStatus, setAddStatus ] = useState( '' );
@@ -367,10 +335,10 @@ const FormAutocompleteMultiselect = React.forwardRef(
367
335
  setCurrentOption( { action: OPTION_ACTION.NONE, option: null } );
368
336
  } else if ( currentOption.index === selectedOptions.length && selectedOptions.length > 0 ) {
369
337
  // Move focus to the first selected item, if the last element is removed and there are other elements in the list
370
- global.document.querySelector( '.vip-button-component' ).focus();
338
+ global.document.querySelector( '.vip-button-component' )?.focus();
371
339
  } else if ( selectedOptions.length === 0 ) {
372
340
  // Move focus to the input field if the last element is removed and there are no other elements in the list
373
- global.document.querySelector( '.autocomplete__input' ).focus();
341
+ global.document.querySelector( '.autocomplete__input' )?.focus();
374
342
  }
375
343
  }, [ currentOption ] );
376
344
 
@@ -421,7 +389,7 @@ const FormAutocompleteMultiselect = React.forwardRef(
421
389
  <div sx={ { display: 'inline-flex', flexWrap: 'wrap', maxWidth: '100%' } }>
422
390
  { selectedOptions &&
423
391
  selectedOptions.map( ( option, idx ) => (
424
- <SelectedOptions
392
+ <ListComponent
425
393
  key={ idx }
426
394
  index={ idx }
427
395
  option={ option }
@@ -29,6 +29,7 @@ declare namespace _default {
29
29
  }
30
30
  export default _default;
31
31
  export function Default(): import("react").JSX.Element;
32
+ export function WithBadges(): import("react").JSX.Element;
32
33
  export function Inline(): import("react").JSX.Element;
33
34
  export namespace Inline {
34
35
  let displayName: string;
@@ -86,6 +86,19 @@ export const Default = () => {
86
86
  );
87
87
  };
88
88
 
89
+ export const WithBadges = () => {
90
+ const customArgs = {
91
+ ...args,
92
+ listType: 'badge',
93
+ };
94
+
95
+ return (
96
+ <>
97
+ <DefaultComponent { ...customArgs } />
98
+ </>
99
+ );
100
+ };
101
+
89
102
  export const Inline = () => {
90
103
  const customArgs = {
91
104
  isInline: true,
@@ -0,0 +1,8 @@
1
+ /** @jsxImportSource theme-ui */
2
+ /// <reference types="react" />
3
+ declare const FormAutocompleteMultiselectBadge: ({ index, option, unselectValue, }: {
4
+ index: number;
5
+ option: string;
6
+ unselectValue: (option: string, index: number) => void;
7
+ }) => import("react").JSX.Element;
8
+ export { FormAutocompleteMultiselectBadge };
@@ -0,0 +1,49 @@
1
+ /** @jsxImportSource theme-ui */
2
+
3
+ /**
4
+ * External dependencies
5
+ */
6
+ import { MdClose } from 'react-icons/md';
7
+ import { Badge } from '..';
8
+ import { jsx as _jsx } from "theme-ui/jsx-runtime";
9
+ import { jsxs as _jsxs } from "theme-ui/jsx-runtime";
10
+ var FormAutocompleteMultiselectBadge = function FormAutocompleteMultiselectBadge(_ref) {
11
+ var index = _ref.index,
12
+ option = _ref.option,
13
+ unselectValue = _ref.unselectValue;
14
+ return _jsx("div", {
15
+ sx: {
16
+ mr: 1,
17
+ maxWidth: '100%'
18
+ },
19
+ children: _jsxs(Badge, {
20
+ variant: "gray",
21
+ sx: {
22
+ mt: 1,
23
+ fontSize: 1,
24
+ maxWidth: '100%',
25
+ display: 'flex',
26
+ alignItems: 'center',
27
+ justifyContent: 'space-between'
28
+ },
29
+ children: [_jsx("div", {
30
+ sx: {
31
+ overflow: 'hidden',
32
+ textOverflow: 'ellipsis',
33
+ whiteSpace: 'nowrap'
34
+ },
35
+ children: option
36
+ }), _jsx(MdClose, {
37
+ sx: {
38
+ ml: 2,
39
+ cursor: 'pointer'
40
+ },
41
+ onClick: function onClick(e) {
42
+ e.preventDefault();
43
+ unselectValue(option, index);
44
+ }
45
+ })]
46
+ })
47
+ }, index);
48
+ };
49
+ export { FormAutocompleteMultiselectBadge };
@@ -0,0 +1,8 @@
1
+ /** @jsxImportSource theme-ui */
2
+ /// <reference types="react" />
3
+ declare const FormAutocompleteMultiselectButton: ({ index, option, unselectValue, }: {
4
+ index: number;
5
+ option: string;
6
+ unselectValue: (option: string, index: number) => void;
7
+ }) => import("react").JSX.Element;
8
+ export { FormAutocompleteMultiselectButton };
@@ -0,0 +1,45 @@
1
+ /** @jsxImportSource theme-ui */
2
+
3
+ /**
4
+ * External dependencies
5
+ */
6
+ import { MdClose } from 'react-icons/md';
7
+ import { Button } from '..';
8
+ import { jsx as _jsx } from "theme-ui/jsx-runtime";
9
+ import { jsxs as _jsxs } from "theme-ui/jsx-runtime";
10
+ var FormAutocompleteMultiselectButton = function FormAutocompleteMultiselectButton(_ref) {
11
+ var index = _ref.index,
12
+ option = _ref.option,
13
+ unselectValue = _ref.unselectValue;
14
+ return _jsx("div", {
15
+ sx: {
16
+ mr: 1,
17
+ maxWidth: '100%'
18
+ },
19
+ children: _jsxs(Button, {
20
+ variant: "tertiary",
21
+ onClick: function onClick(e) {
22
+ e.preventDefault();
23
+ unselectValue(option, index);
24
+ },
25
+ sx: {
26
+ mt: 1,
27
+ fontSize: 1,
28
+ maxWidth: '100%'
29
+ },
30
+ children: [_jsx("div", {
31
+ sx: {
32
+ overflow: 'hidden',
33
+ textOverflow: 'ellipsis',
34
+ whiteSpace: 'nowrap'
35
+ },
36
+ children: option
37
+ }), _jsx(MdClose, {
38
+ sx: {
39
+ ml: 2
40
+ }
41
+ })]
42
+ })
43
+ }, index);
44
+ };
45
+ export { FormAutocompleteMultiselectButton };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/vip-design-system",
3
- "version": "2.15.2",
3
+ "version": "2.15.3",
4
4
  "main": "build/system/index.js",
5
5
  "scripts": {
6
6
  "build-storybook": "storybook build",
@@ -7,16 +7,17 @@ import Autocomplete from 'accessible-autocomplete/react';
7
7
  import classNames from 'classnames';
8
8
  import PropTypes from 'prop-types';
9
9
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
10
- import { MdClose } from 'react-icons/md';
11
10
 
12
11
  /**
13
12
  * Internal dependencies
14
13
  */
14
+ import { FormAutocompleteMultiselectBadge } from './FormAutocompleteMultiselectBadge';
15
+ import { FormAutocompleteMultiselectButton } from './FormAutocompleteMultiselectButton';
15
16
  import { FormSelectArrow } from './FormSelectArrow';
16
17
  import { FormSelectContent } from './FormSelectContent';
17
18
  import { FormSelectLoading } from './FormSelectLoading';
18
19
  import { FormSelectSearch } from './FormSelectSearch';
19
- import { Button, Flex } from '../';
20
+ import { Flex } from '../';
20
21
  import { Validation } from '../Form';
21
22
  import { baseControlBorderStyle, inputBaseText } from '../Form/Input.styles';
22
23
  import { Label } from '../Form/Label';
@@ -126,42 +127,6 @@ AddSelectionStatus.propTypes = {
126
127
  status: PropTypes.string.isRequired,
127
128
  };
128
129
 
129
- const SelectedOptions = ( { index, option, unselectValue } ) => {
130
- return (
131
- <div key={ index } sx={ { mr: 1, maxWidth: '100%' } }>
132
- <Button
133
- variant="tertiary"
134
- onClick={ e => {
135
- e.preventDefault();
136
- unselectValue( option, index );
137
- } }
138
- sx={ {
139
- mt: 1,
140
- fontSize: 1,
141
- maxWidth: '100%',
142
- } }
143
- >
144
- <div
145
- sx={ {
146
- overflow: 'hidden',
147
- textOverflow: 'ellipsis',
148
- whiteSpace: 'nowrap',
149
- } }
150
- >
151
- { option }
152
- </div>
153
- <MdClose sx={ { ml: 2 } } />
154
- </Button>
155
- </div>
156
- );
157
- };
158
-
159
- SelectedOptions.propTypes = {
160
- index: PropTypes.number.isRequired,
161
- option: PropTypes.string.isRequired,
162
- unselectValue: PropTypes.func.isRequired,
163
- };
164
-
165
130
  const FormAutocompleteMultiselect = React.forwardRef(
166
131
  (
167
132
  {
@@ -188,6 +153,7 @@ const FormAutocompleteMultiselect = React.forwardRef(
188
153
  showAllValues = false,
189
154
  source,
190
155
  value,
156
+ listType = 'button',
191
157
  ...props
192
158
  },
193
159
  forwardRef
@@ -197,6 +163,8 @@ const FormAutocompleteMultiselect = React.forwardRef(
197
163
  REMOVE: 'remove',
198
164
  NONE: 'none',
199
165
  };
166
+ const ListComponent =
167
+ listType === 'button' ? FormAutocompleteMultiselectButton : FormAutocompleteMultiselectBadge;
200
168
  const [ isDirty, setIsDirty ] = useState( false );
201
169
  const [ selectedOptions, setSelectedOptions ] = useState( [] );
202
170
  const [ addStatus, setAddStatus ] = useState( '' );
@@ -367,10 +335,10 @@ const FormAutocompleteMultiselect = React.forwardRef(
367
335
  setCurrentOption( { action: OPTION_ACTION.NONE, option: null } );
368
336
  } else if ( currentOption.index === selectedOptions.length && selectedOptions.length > 0 ) {
369
337
  // Move focus to the first selected item, if the last element is removed and there are other elements in the list
370
- global.document.querySelector( '.vip-button-component' ).focus();
338
+ global.document.querySelector( '.vip-button-component' )?.focus();
371
339
  } else if ( selectedOptions.length === 0 ) {
372
340
  // Move focus to the input field if the last element is removed and there are no other elements in the list
373
- global.document.querySelector( '.autocomplete__input' ).focus();
341
+ global.document.querySelector( '.autocomplete__input' )?.focus();
374
342
  }
375
343
  }, [ currentOption ] );
376
344
 
@@ -421,7 +389,7 @@ const FormAutocompleteMultiselect = React.forwardRef(
421
389
  <div sx={ { display: 'inline-flex', flexWrap: 'wrap', maxWidth: '100%' } }>
422
390
  { selectedOptions &&
423
391
  selectedOptions.map( ( option, idx ) => (
424
- <SelectedOptions
392
+ <ListComponent
425
393
  key={ idx }
426
394
  index={ idx }
427
395
  option={ option }
@@ -86,6 +86,19 @@ export const Default = () => {
86
86
  );
87
87
  };
88
88
 
89
+ export const WithBadges = () => {
90
+ const customArgs = {
91
+ ...args,
92
+ listType: 'badge',
93
+ };
94
+
95
+ return (
96
+ <>
97
+ <DefaultComponent { ...customArgs } />
98
+ </>
99
+ );
100
+ };
101
+
89
102
  export const Inline = () => {
90
103
  const customArgs = {
91
104
  isInline: true,
@@ -0,0 +1,53 @@
1
+ /** @jsxImportSource theme-ui */
2
+
3
+ /**
4
+ * External dependencies
5
+ */
6
+ import { MdClose } from 'react-icons/md';
7
+
8
+ import { Badge } from '..';
9
+
10
+ const FormAutocompleteMultiselectBadge = ( {
11
+ index,
12
+ option,
13
+ unselectValue,
14
+ }: {
15
+ index: number;
16
+ option: string;
17
+ unselectValue: ( option: string, index: number ) => void;
18
+ } ) => {
19
+ return (
20
+ <div key={ index } sx={ { mr: 1, maxWidth: '100%' } }>
21
+ <Badge
22
+ variant="gray"
23
+ sx={ {
24
+ mt: 1,
25
+ fontSize: 1,
26
+ maxWidth: '100%',
27
+ display: 'flex',
28
+ alignItems: 'center',
29
+ justifyContent: 'space-between',
30
+ } }
31
+ >
32
+ <div
33
+ sx={ {
34
+ overflow: 'hidden',
35
+ textOverflow: 'ellipsis',
36
+ whiteSpace: 'nowrap',
37
+ } }
38
+ >
39
+ { option }
40
+ </div>
41
+ <MdClose
42
+ sx={ { ml: 2, cursor: 'pointer' } }
43
+ onClick={ e => {
44
+ e.preventDefault();
45
+ unselectValue( option, index );
46
+ } }
47
+ />
48
+ </Badge>
49
+ </div>
50
+ );
51
+ };
52
+
53
+ export { FormAutocompleteMultiselectBadge };
@@ -0,0 +1,48 @@
1
+ /** @jsxImportSource theme-ui */
2
+
3
+ /**
4
+ * External dependencies
5
+ */
6
+ import { MdClose } from 'react-icons/md';
7
+
8
+ import { Button } from '..';
9
+
10
+ const FormAutocompleteMultiselectButton = ( {
11
+ index,
12
+ option,
13
+ unselectValue,
14
+ }: {
15
+ index: number;
16
+ option: string;
17
+ unselectValue: ( option: string, index: number ) => void;
18
+ } ) => {
19
+ return (
20
+ <div key={ index } sx={ { mr: 1, maxWidth: '100%' } }>
21
+ <Button
22
+ variant="tertiary"
23
+ onClick={ e => {
24
+ e.preventDefault();
25
+ unselectValue( option, index );
26
+ } }
27
+ sx={ {
28
+ mt: 1,
29
+ fontSize: 1,
30
+ maxWidth: '100%',
31
+ } }
32
+ >
33
+ <div
34
+ sx={ {
35
+ overflow: 'hidden',
36
+ textOverflow: 'ellipsis',
37
+ whiteSpace: 'nowrap',
38
+ } }
39
+ >
40
+ { option }
41
+ </div>
42
+ <MdClose sx={ { ml: 2 } } />
43
+ </Button>
44
+ </div>
45
+ );
46
+ };
47
+
48
+ export { FormAutocompleteMultiselectButton };