@automattic/vip-design-system 2.15.4 → 2.15.6

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.
@@ -85,6 +85,12 @@ const inlineStyles = {
85
85
  borderWidth: 0,
86
86
  };
87
87
 
88
+ const allowCustomStyles = {
89
+ '& .autocomplete__option--no-results': {
90
+ cursor: 'pointer',
91
+ },
92
+ };
93
+
88
94
  const searchIconStyles = {
89
95
  '& .autocomplete__input.autocomplete__input': {
90
96
  paddingLeft: 6,
@@ -120,6 +126,7 @@ const FormAutocomplete = React.forwardRef(
120
126
  resetOnBlur = false, // resets the input value to the selection if the input is blurred. Returns null if selection is empty
121
127
  source,
122
128
  value,
129
+ allowCustom = false,
123
130
  ...props
124
131
  },
125
132
  forwardRef
@@ -199,9 +206,13 @@ const FormAutocomplete = React.forwardRef(
199
206
 
200
207
  const handleTypeChange = useCallback(
201
208
  query => {
202
- return options.filter(
209
+ const filteredOptions = options.filter(
203
210
  option => optionLabel( option ).toLowerCase().indexOf( query.toLowerCase() ) >= 0
204
211
  );
212
+ if ( allowCustom && filteredOptions.length === 0 ) {
213
+ return [ { label: query, value: query } ];
214
+ }
215
+ return filteredOptions;
205
216
  },
206
217
  [ options ]
207
218
  );
@@ -319,6 +330,7 @@ const FormAutocomplete = React.forwardRef(
319
330
  ...defaultStyles,
320
331
  ...( isInline && inlineStyles ),
321
332
  ...( searchIcon && searchIconStyles ),
333
+ ...( allowCustom && allowCustomStyles ),
322
334
  ...( hasError ? { borderColor: 'input.border.error' } : {} ),
323
335
  } }
324
336
  >
@@ -382,6 +394,7 @@ FormAutocomplete.propTypes = {
382
394
  source: PropTypes.func,
383
395
  value: PropTypes.string,
384
396
  dropdownArrow: PropTypes.node,
397
+ allowCustom: PropTypes.bool,
385
398
  };
386
399
 
387
400
  FormAutocomplete.displayName = 'FormAutocomplete';
@@ -58,42 +58,51 @@ export function Default({ label, width, ...rest }: {
58
58
  export namespace Default {
59
59
  export { args };
60
60
  }
61
- export function Inline({ label, width, ...rest }: {
61
+ export function WithAllowCustom({ label, width, ...rest }: {
62
62
  [x: string]: any;
63
63
  label?: string | undefined;
64
64
  width?: number | undefined;
65
65
  }): import("react").JSX.Element;
66
- export namespace Inline {
66
+ export namespace WithAllowCustom {
67
67
  let args_1: any;
68
68
  export { args_1 as args };
69
69
  }
70
- export function WithDefaultValue({ label, width, ...rest }: {
70
+ export function Inline({ label, width, ...rest }: {
71
71
  [x: string]: any;
72
72
  label?: string | undefined;
73
73
  width?: number | undefined;
74
74
  }): import("react").JSX.Element;
75
- export namespace WithDefaultValue {
75
+ export namespace Inline {
76
76
  let args_2: any;
77
77
  export { args_2 as args };
78
78
  }
79
- export function WithSearchIcon({ label, width, ...rest }: {
79
+ export function WithDefaultValue({ label, width, ...rest }: {
80
80
  [x: string]: any;
81
81
  label?: string | undefined;
82
82
  width?: number | undefined;
83
83
  }): import("react").JSX.Element;
84
- export namespace WithSearchIcon {
84
+ export namespace WithDefaultValue {
85
85
  let args_3: any;
86
86
  export { args_3 as args };
87
87
  }
88
- export function WithLoading({ label, width, ...rest }: {
88
+ export function WithSearchIcon({ label, width, ...rest }: {
89
89
  [x: string]: any;
90
90
  label?: string | undefined;
91
91
  width?: number | undefined;
92
92
  }): import("react").JSX.Element;
93
- export namespace WithLoading {
93
+ export namespace WithSearchIcon {
94
94
  let args_4: any;
95
95
  export { args_4 as args };
96
96
  }
97
+ export function WithLoading({ label, width, ...rest }: {
98
+ [x: string]: any;
99
+ label?: string | undefined;
100
+ width?: number | undefined;
101
+ }): import("react").JSX.Element;
102
+ export namespace WithLoading {
103
+ let args_5: any;
104
+ export { args_5 as args };
105
+ }
97
106
  export function WithDebounce(): import("react").JSX.Element;
98
107
  export function WithSlowSearchAndDebounce({ label, width, ...rest }: {
99
108
  [x: string]: any;
@@ -101,8 +110,8 @@ export function WithSlowSearchAndDebounce({ label, width, ...rest }: {
101
110
  width?: number | undefined;
102
111
  }): import("react").JSX.Element;
103
112
  export namespace WithSlowSearchAndDebounce {
104
- let args_5: any;
105
- export { args_5 as args };
113
+ let args_6: any;
114
+ export { args_6 as args };
106
115
  }
107
116
  export function WithCustomMessages({ label, width, ...rest }: {
108
117
  [x: string]: any;
@@ -110,8 +119,8 @@ export function WithCustomMessages({ label, width, ...rest }: {
110
119
  width?: number | undefined;
111
120
  }): import("react").JSX.Element;
112
121
  export namespace WithCustomMessages {
113
- let args_6: any;
114
- export { args_6 as args };
122
+ let args_7: any;
123
+ export { args_7 as args };
115
124
  }
116
125
  export function WithErrors({ label, width, ...rest }: {
117
126
  [x: string]: any;
@@ -119,8 +128,8 @@ export function WithErrors({ label, width, ...rest }: {
119
128
  width?: number | undefined;
120
129
  }): import("react").JSX.Element;
121
130
  export namespace WithErrors {
122
- let args_7: any;
123
- export { args_7 as args };
131
+ let args_8: any;
132
+ export { args_8 as args };
124
133
  }
125
134
  export function WithArrow({ label, width, ...rest }: {
126
135
  [x: string]: any;
@@ -128,8 +137,8 @@ export function WithArrow({ label, width, ...rest }: {
128
137
  width?: number | undefined;
129
138
  }): import("react").JSX.Element;
130
139
  export namespace WithArrow {
131
- let args_8: any;
132
- export { args_8 as args };
140
+ let args_9: any;
141
+ export { args_9 as args };
133
142
  }
134
143
  export function WithCustomArrow({ label, width, ...rest }: {
135
144
  [x: string]: any;
@@ -137,8 +146,8 @@ export function WithCustomArrow({ label, width, ...rest }: {
137
146
  width?: number | undefined;
138
147
  }): import("react").JSX.Element;
139
148
  export namespace WithCustomArrow {
140
- let args_9: any;
141
- export { args_9 as args };
149
+ let args_10: any;
150
+ export { args_10 as args };
142
151
  export let displayName: string;
143
152
  }
144
153
  declare namespace args {
@@ -67,6 +67,12 @@ const DefaultComponent = ( { label = 'Label', width = 250, ...rest } ) => {
67
67
  export const Default = DefaultComponent.bind( {} );
68
68
  Default.args = args;
69
69
 
70
+ export const WithAllowCustom = DefaultComponent.bind( {} );
71
+ WithAllowCustom.args = {
72
+ ...Default.args,
73
+ allowCustom: true,
74
+ };
75
+
70
76
  export const Inline = DefaultComponent.bind( {} );
71
77
  Inline.args = {
72
78
  ...Default.args,
@@ -155,6 +155,7 @@ const FormAutocompleteMultiselect = React.forwardRef(
155
155
  value,
156
156
  listType = 'button',
157
157
  initialValue = [],
158
+ allowCustom = false,
158
159
  ...props
159
160
  },
160
161
  forwardRef
@@ -245,11 +246,16 @@ const FormAutocompleteMultiselect = React.forwardRef(
245
246
  );
246
247
 
247
248
  const handleTypeChange = useCallback(
248
- query =>
249
- options.filter(
249
+ query => {
250
+ const filteredOptions = options.filter(
250
251
  option => optionLabel( option ).toLowerCase().indexOf( query.toLowerCase() ) >= 0
251
- ),
252
- [ options ]
252
+ );
253
+ if ( allowCustom && filteredOptions.length === 0 ) {
254
+ return [ { label: query, value: query } ];
255
+ }
256
+ return filteredOptions;
257
+ },
258
+ [ options, allowCustom ]
253
259
  );
254
260
 
255
261
  const handleInputChange = useCallback(
@@ -384,7 +390,7 @@ const FormAutocompleteMultiselect = React.forwardRef(
384
390
  </Validation>
385
391
  ) }
386
392
  <div sx={ { fontSize: 1 } }>
387
- { selectedOptions.length } item{ selectedOptions.length > 1 ? 's' : '' } selected
393
+ { selectedOptions.length } item{ selectedOptions.length === 1 ? '' : 's' } selected
388
394
  </div>
389
395
  </Flex>
390
396
  <div sx={ { display: 'inline-flex', flexWrap: 'wrap', maxWidth: '100%' } }>
@@ -428,6 +434,7 @@ FormAutocompleteMultiselect.propTypes = {
428
434
  value: PropTypes.string,
429
435
  dropdownArrow: PropTypes.node,
430
436
  initialValue: PropTypes.array,
437
+ allowCustom: PropTypes.bool,
431
438
  };
432
439
 
433
440
  FormAutocompleteMultiselect.displayName = 'FormAutocompleteMultiselect';
@@ -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 WithAllowCustom(): import("react").JSX.Element;
32
33
  export function WithBadges(): import("react").JSX.Element;
33
34
  export function WithInitialValueBadges(): import("react").JSX.Element;
34
35
  export function Inline(): import("react").JSX.Element;
@@ -86,6 +86,15 @@ export const Default = () => {
86
86
  );
87
87
  };
88
88
 
89
+ export const WithAllowCustom = () => {
90
+ const customArgs = {
91
+ ...args,
92
+ allowCustom: true,
93
+ };
94
+
95
+ return <DefaultComponent { ...customArgs } />;
96
+ };
97
+
89
98
  export const WithBadges = () => {
90
99
  const customArgs = {
91
100
  ...args,
@@ -6,16 +6,23 @@ function _extends() { _extends = Object.assign ? Object.assign.bind() : function
6
6
  */
7
7
  import React from 'react';
8
8
  import { MdSearch } from 'react-icons/md';
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import { Box } from '../Box';
9
13
  import { jsx as _jsx } from "theme-ui/jsx-runtime";
10
- var searchStyles = {
14
+ var wrapperStyles = {
11
15
  position: 'absolute',
16
+ left: 3
17
+ };
18
+ var searchStyles = {
12
19
  pr: 2,
13
- left: 3,
14
20
  pointerEvents: 'none'
15
21
  };
16
22
  export var FormSelectSearch = /*#__PURE__*/React.forwardRef(function (props, forwardRef) {
17
- return _jsx("div", {
23
+ return _jsx(Box, {
18
24
  ref: forwardRef,
25
+ sx: wrapperStyles,
19
26
  children: _jsx(MdSearch, _extends({
20
27
  "aria-hidden": "true",
21
28
  size: 24,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/vip-design-system",
3
- "version": "2.15.4",
3
+ "version": "2.15.6",
4
4
  "main": "build/system/index.js",
5
5
  "scripts": {
6
6
  "build-storybook": "storybook build",
@@ -85,6 +85,12 @@ const inlineStyles = {
85
85
  borderWidth: 0,
86
86
  };
87
87
 
88
+ const allowCustomStyles = {
89
+ '& .autocomplete__option--no-results': {
90
+ cursor: 'pointer',
91
+ },
92
+ };
93
+
88
94
  const searchIconStyles = {
89
95
  '& .autocomplete__input.autocomplete__input': {
90
96
  paddingLeft: 6,
@@ -120,6 +126,7 @@ const FormAutocomplete = React.forwardRef(
120
126
  resetOnBlur = false, // resets the input value to the selection if the input is blurred. Returns null if selection is empty
121
127
  source,
122
128
  value,
129
+ allowCustom = false,
123
130
  ...props
124
131
  },
125
132
  forwardRef
@@ -199,9 +206,13 @@ const FormAutocomplete = React.forwardRef(
199
206
 
200
207
  const handleTypeChange = useCallback(
201
208
  query => {
202
- return options.filter(
209
+ const filteredOptions = options.filter(
203
210
  option => optionLabel( option ).toLowerCase().indexOf( query.toLowerCase() ) >= 0
204
211
  );
212
+ if ( allowCustom && filteredOptions.length === 0 ) {
213
+ return [ { label: query, value: query } ];
214
+ }
215
+ return filteredOptions;
205
216
  },
206
217
  [ options ]
207
218
  );
@@ -319,6 +330,7 @@ const FormAutocomplete = React.forwardRef(
319
330
  ...defaultStyles,
320
331
  ...( isInline && inlineStyles ),
321
332
  ...( searchIcon && searchIconStyles ),
333
+ ...( allowCustom && allowCustomStyles ),
322
334
  ...( hasError ? { borderColor: 'input.border.error' } : {} ),
323
335
  } }
324
336
  >
@@ -382,6 +394,7 @@ FormAutocomplete.propTypes = {
382
394
  source: PropTypes.func,
383
395
  value: PropTypes.string,
384
396
  dropdownArrow: PropTypes.node,
397
+ allowCustom: PropTypes.bool,
385
398
  };
386
399
 
387
400
  FormAutocomplete.displayName = 'FormAutocomplete';
@@ -67,6 +67,12 @@ const DefaultComponent = ( { label = 'Label', width = 250, ...rest } ) => {
67
67
  export const Default = DefaultComponent.bind( {} );
68
68
  Default.args = args;
69
69
 
70
+ export const WithAllowCustom = DefaultComponent.bind( {} );
71
+ WithAllowCustom.args = {
72
+ ...Default.args,
73
+ allowCustom: true,
74
+ };
75
+
70
76
  export const Inline = DefaultComponent.bind( {} );
71
77
  Inline.args = {
72
78
  ...Default.args,
@@ -155,6 +155,7 @@ const FormAutocompleteMultiselect = React.forwardRef(
155
155
  value,
156
156
  listType = 'button',
157
157
  initialValue = [],
158
+ allowCustom = false,
158
159
  ...props
159
160
  },
160
161
  forwardRef
@@ -245,11 +246,16 @@ const FormAutocompleteMultiselect = React.forwardRef(
245
246
  );
246
247
 
247
248
  const handleTypeChange = useCallback(
248
- query =>
249
- options.filter(
249
+ query => {
250
+ const filteredOptions = options.filter(
250
251
  option => optionLabel( option ).toLowerCase().indexOf( query.toLowerCase() ) >= 0
251
- ),
252
- [ options ]
252
+ );
253
+ if ( allowCustom && filteredOptions.length === 0 ) {
254
+ return [ { label: query, value: query } ];
255
+ }
256
+ return filteredOptions;
257
+ },
258
+ [ options, allowCustom ]
253
259
  );
254
260
 
255
261
  const handleInputChange = useCallback(
@@ -384,7 +390,7 @@ const FormAutocompleteMultiselect = React.forwardRef(
384
390
  </Validation>
385
391
  ) }
386
392
  <div sx={ { fontSize: 1 } }>
387
- { selectedOptions.length } item{ selectedOptions.length > 1 ? 's' : '' } selected
393
+ { selectedOptions.length } item{ selectedOptions.length === 1 ? '' : 's' } selected
388
394
  </div>
389
395
  </Flex>
390
396
  <div sx={ { display: 'inline-flex', flexWrap: 'wrap', maxWidth: '100%' } }>
@@ -428,6 +434,7 @@ FormAutocompleteMultiselect.propTypes = {
428
434
  value: PropTypes.string,
429
435
  dropdownArrow: PropTypes.node,
430
436
  initialValue: PropTypes.array,
437
+ allowCustom: PropTypes.bool,
431
438
  };
432
439
 
433
440
  FormAutocompleteMultiselect.displayName = 'FormAutocompleteMultiselect';
@@ -86,6 +86,15 @@ export const Default = () => {
86
86
  );
87
87
  };
88
88
 
89
+ export const WithAllowCustom = () => {
90
+ const customArgs = {
91
+ ...args,
92
+ allowCustom: true,
93
+ };
94
+
95
+ return <DefaultComponent { ...customArgs } />;
96
+ };
97
+
89
98
  export const WithBadges = () => {
90
99
  const customArgs = {
91
100
  ...args,
@@ -7,22 +7,30 @@ import React from 'react';
7
7
  import { MdSearch } from 'react-icons/md';
8
8
  import { ThemeUIStyleObject } from 'theme-ui';
9
9
 
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import { Box } from '../Box';
14
+
10
15
  interface FormSelectSearchProps {
11
16
  sx?: ThemeUIStyleObject;
12
17
  }
13
18
 
14
- const searchStyles: ThemeUIStyleObject = {
19
+ const wrapperStyles: ThemeUIStyleObject = {
15
20
  position: 'absolute',
16
- pr: 2,
17
21
  left: 3,
22
+ };
23
+
24
+ const searchStyles: ThemeUIStyleObject = {
25
+ pr: 2,
18
26
  pointerEvents: 'none',
19
27
  };
20
28
 
21
29
  export const FormSelectSearch = React.forwardRef< SVGSVGElement, FormSelectSearchProps >(
22
30
  ( props, forwardRef ) => (
23
- <div ref={ forwardRef as React.RefObject< HTMLDivElement > }>
31
+ <Box ref={ forwardRef as React.RefObject< HTMLDivElement > } sx={ wrapperStyles }>
24
32
  <MdSearch aria-hidden="true" size={ 24 } sx={ searchStyles } { ...props } />
25
- </div>
33
+ </Box>
26
34
  )
27
35
  );
28
36