@leafygreen-ui/combobox 8.1.3 → 9.0.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.
- package/CHANGELOG.md +55 -0
- package/README.md +34 -33
- package/dist/Combobox/Combobox.d.ts +2 -2
- package/dist/Combobox/Combobox.d.ts.map +1 -1
- package/dist/Combobox/Combobox.styles.d.ts +9 -8
- package/dist/Combobox/Combobox.styles.d.ts.map +1 -1
- package/dist/Combobox/Combobox.types.d.ts +5 -1
- package/dist/Combobox/Combobox.types.d.ts.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/types/Combobox.types.d.ts +7 -6
- package/dist/types/Combobox.types.d.ts.map +1 -1
- package/package.json +8 -7
- package/src/Combobox/Combobox.spec.tsx +9 -0
- package/src/Combobox/Combobox.styles.ts +49 -79
- package/src/Combobox/Combobox.tsx +24 -34
- package/src/Combobox/Combobox.types.ts +6 -1
- package/src/Combobox.stories.tsx +2 -2
- package/src/ComboboxContext/ComboboxContext.tsx +2 -2
- package/src/types/Combobox.types.ts +7 -8
- package/stories.js +1 -1
- package/tsconfig.json +3 -0
- package/tsdoc.json +85 -2
|
@@ -39,17 +39,18 @@ export declare const Overflow: {
|
|
|
39
39
|
readonly expandX: "expand-x";
|
|
40
40
|
};
|
|
41
41
|
export type Overflow = (typeof Overflow)[keyof typeof Overflow];
|
|
42
|
-
/** The error state of the Combobox */
|
|
42
|
+
/** The error/valid state of the Combobox */
|
|
43
43
|
export declare const State: {
|
|
44
|
-
readonly
|
|
45
|
-
readonly
|
|
44
|
+
readonly None: "none";
|
|
45
|
+
readonly Error: "error";
|
|
46
|
+
readonly Valid: "valid";
|
|
46
47
|
};
|
|
47
48
|
export type State = (typeof State)[keyof typeof State];
|
|
48
49
|
/** The search state of the Combobox */
|
|
49
50
|
export declare const SearchState: {
|
|
50
|
-
readonly
|
|
51
|
-
readonly
|
|
52
|
-
readonly
|
|
51
|
+
readonly Unset: "unset";
|
|
52
|
+
readonly Error: "error";
|
|
53
|
+
readonly Loading: "loading";
|
|
53
54
|
};
|
|
54
55
|
export type SearchState = (typeof SearchState)[keyof typeof SearchState];
|
|
55
56
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Combobox.types.d.ts","sourceRoot":"","sources":["../../src/types/Combobox.types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Combobox.types.d.ts","sourceRoot":"","sources":["../../src/types/Combobox.types.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;CAQlB,CAAC;AACX,MAAM,MAAM,eAAe,GACzB,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,YAAY;;;;;CAKf,CAAC;AACX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAE5E;;GAEG;AACH,eAAO,MAAM,QAAQ;IACnB;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;CAEK,CAAC;AACX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,OAAO,QAAQ,CAAC,CAAC;AAEhE,4CAA4C;AAC5C,eAAO,MAAM,KAAK;;;;CAAiB,CAAC;AACpC,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,OAAO,KAAK,CAAC,CAAC;AAEvD,uCAAuC;AACvC,eAAO,MAAM,WAAW;;;;CAId,CAAC;AACX,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,CAAC;AAEzE;;;;;GAKG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,OAAO,IAAI,CAAC,SAAS,IAAI,GAC3D,KAAK,CAAC,MAAM,CAAC,GACb,MAAM,GAAG,IAAI,CAAC;AAElB,uFAAuF;AACvF,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC9B,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;CAC/B;AAED;;;;GAIG;AAEH,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,OAAO,IAAI,CAAC,SAAS,IAAI,GACxD,CAAC,KAAK,EAAE,eAAe,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,UAAU,KAAK,IAAI,GACzD,CAAC,KAAK,EAAE,eAAe,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;AAE5C;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,OAAO,EAChD,WAAW,EAAE,CAAC,GACb,eAAe,CAAC,CAAC,CAAC,CAMpB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leafygreen-ui/combobox",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "9.0.0",
|
|
4
4
|
"description": "leafyGreen UI Kit Combobox",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -22,18 +22,19 @@
|
|
|
22
22
|
"access": "public"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@leafygreen-ui/checkbox": "^13.
|
|
25
|
+
"@leafygreen-ui/checkbox": "^13.1.0",
|
|
26
26
|
"@leafygreen-ui/chip": "^1.0.2",
|
|
27
27
|
"@leafygreen-ui/emotion": "^4.0.8",
|
|
28
|
+
"@leafygreen-ui/form-field": "^1.2.0",
|
|
28
29
|
"@leafygreen-ui/hooks": "^8.1.3",
|
|
29
30
|
"@leafygreen-ui/icon": "^12.0.1",
|
|
30
31
|
"@leafygreen-ui/icon-button": "^15.0.21",
|
|
31
|
-
"@leafygreen-ui/input-option": "^1.1.
|
|
32
|
+
"@leafygreen-ui/input-option": "^1.1.3",
|
|
32
33
|
"@leafygreen-ui/lib": "^13.3.0",
|
|
33
34
|
"@leafygreen-ui/palette": "^4.0.9",
|
|
34
35
|
"@leafygreen-ui/popover": "^11.3.1",
|
|
35
|
-
"@leafygreen-ui/tokens": "^2.
|
|
36
|
-
"@leafygreen-ui/typography": "^
|
|
36
|
+
"@leafygreen-ui/tokens": "^2.6.0",
|
|
37
|
+
"@leafygreen-ui/typography": "^19.1.0",
|
|
37
38
|
"chalk": "^4.1.2",
|
|
38
39
|
"lodash": "^4.17.21",
|
|
39
40
|
"polished": "^4.2.2"
|
|
@@ -42,9 +43,9 @@
|
|
|
42
43
|
"@leafygreen-ui/leafygreen-provider": "^3.1.12"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
|
-
"@leafygreen-ui/button": "^21.
|
|
46
|
+
"@leafygreen-ui/button": "^21.2.0",
|
|
46
47
|
"@leafygreen-ui/testing-lib": "^0.4.2",
|
|
47
|
-
"@lg-tools/storybook-utils": "^0.1.
|
|
48
|
+
"@lg-tools/storybook-utils": "^0.1.1"
|
|
48
49
|
},
|
|
49
50
|
"homepage": "https://github.com/mongodb/leafygreen-ui/tree/main/packages/combobox",
|
|
50
51
|
"repository": {
|
|
@@ -344,6 +344,15 @@ describe('packages/combobox', () => {
|
|
|
344
344
|
});
|
|
345
345
|
|
|
346
346
|
describe('When disabled', () => {
|
|
347
|
+
test(`Input element renders with aria-disabled and readonly attributes but not disabled attribute when disabled prop is set`, () => {
|
|
348
|
+
const { inputEl } = renderCombobox(select, {
|
|
349
|
+
disabled: true,
|
|
350
|
+
});
|
|
351
|
+
expect(inputEl.getAttribute('aria-disabled')).toBeTruthy();
|
|
352
|
+
expect(inputEl.hasAttribute('readonly')).toBeTruthy();
|
|
353
|
+
expect(inputEl.getAttribute('disabled')).toBeFalsy();
|
|
354
|
+
});
|
|
355
|
+
|
|
347
356
|
// disabled prop
|
|
348
357
|
test('Combobox is not clickable when `disabled`', () => {
|
|
349
358
|
const { comboboxEl } = renderCombobox(select, { disabled: true });
|
|
@@ -4,6 +4,7 @@ import { css } from '@leafygreen-ui/emotion';
|
|
|
4
4
|
import { Theme } from '@leafygreen-ui/lib';
|
|
5
5
|
import { palette } from '@leafygreen-ui/palette';
|
|
6
6
|
import {
|
|
7
|
+
color,
|
|
7
8
|
focusRing,
|
|
8
9
|
fontFamilies,
|
|
9
10
|
spacing,
|
|
@@ -17,7 +18,7 @@ import {
|
|
|
17
18
|
fontSize,
|
|
18
19
|
lineHeight,
|
|
19
20
|
} from '../ComboboxChip/ComboboxChip.styles';
|
|
20
|
-
import { ComboboxSize as Size, Overflow } from '../types';
|
|
21
|
+
import { ComboboxSize as Size, Overflow, State } from '../types';
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* Util to get the chip height
|
|
@@ -29,7 +30,7 @@ const inputHeight = (size: Size) => {
|
|
|
29
30
|
};
|
|
30
31
|
|
|
31
32
|
// Gap between each chip
|
|
32
|
-
const flexGap =
|
|
33
|
+
const flexGap = spacing[100];
|
|
33
34
|
|
|
34
35
|
/**
|
|
35
36
|
* The min-height of the combobox.
|
|
@@ -64,27 +65,27 @@ export const comboboxPadding: Record<
|
|
|
64
65
|
> = {
|
|
65
66
|
[Size.XSmall]: {
|
|
66
67
|
y: getYPadding(Size.XSmall),
|
|
67
|
-
xLeftWithChip:
|
|
68
|
-
xLeftWithoutChip:
|
|
69
|
-
xRight:
|
|
68
|
+
xLeftWithChip: spacing[25],
|
|
69
|
+
xLeftWithoutChip: spacing[200],
|
|
70
|
+
xRight: spacing[100],
|
|
70
71
|
},
|
|
71
72
|
[Size.Small]: {
|
|
72
73
|
y: getYPadding(Size.Small),
|
|
73
|
-
xLeftWithChip:
|
|
74
|
-
xLeftWithoutChip:
|
|
75
|
-
xRight:
|
|
74
|
+
xLeftWithChip: spacing[100],
|
|
75
|
+
xLeftWithoutChip: spacing[200],
|
|
76
|
+
xRight: spacing[100],
|
|
76
77
|
},
|
|
77
78
|
[Size.Default]: {
|
|
78
79
|
y: getYPadding(Size.Default),
|
|
79
|
-
xLeftWithChip:
|
|
80
|
-
xLeftWithoutChip:
|
|
81
|
-
xRight:
|
|
80
|
+
xLeftWithChip: spacing[150],
|
|
81
|
+
xLeftWithoutChip: spacing[300],
|
|
82
|
+
xRight: spacing[200],
|
|
82
83
|
},
|
|
83
84
|
[Size.Large]: {
|
|
84
85
|
y: getYPadding(Size.Large),
|
|
85
|
-
xLeftWithChip: spacing[
|
|
86
|
-
xLeftWithoutChip: spacing[
|
|
87
|
-
xRight: spacing[
|
|
86
|
+
xLeftWithChip: spacing[300],
|
|
87
|
+
xLeftWithoutChip: spacing[300],
|
|
88
|
+
xRight: spacing[200],
|
|
88
89
|
},
|
|
89
90
|
};
|
|
90
91
|
|
|
@@ -92,7 +93,7 @@ export const comboboxPadding: Record<
|
|
|
92
93
|
export const clearButtonIconSize = 28;
|
|
93
94
|
|
|
94
95
|
/** Width of the dropdown caret icon (in px) */
|
|
95
|
-
export const caretIconSize = spacing[
|
|
96
|
+
export const caretIconSize = spacing[400];
|
|
96
97
|
|
|
97
98
|
export const comboboxParentStyle = (size: Size): string => {
|
|
98
99
|
return css`
|
|
@@ -108,7 +109,7 @@ export const comboboxParentStyle = (size: Size): string => {
|
|
|
108
109
|
export const baseComboboxStyles = css`
|
|
109
110
|
display: flex;
|
|
110
111
|
align-items: center;
|
|
111
|
-
gap: ${spacing[
|
|
112
|
+
gap: ${spacing[200]}px;
|
|
112
113
|
cursor: text;
|
|
113
114
|
transition: ${transitionDuration.default}ms ease-in-out;
|
|
114
115
|
transition-property: background-color, box-shadow, border-color;
|
|
@@ -137,14 +138,12 @@ export const baseComboboxStyles = css`
|
|
|
137
138
|
|
|
138
139
|
export const comboboxThemeStyles: Record<Theme, string> = {
|
|
139
140
|
[Theme.Light]: css`
|
|
140
|
-
color: ${
|
|
141
|
-
background-color: ${
|
|
142
|
-
border-color: ${palette.gray.base};
|
|
141
|
+
color: ${color.light.text.primary.default};
|
|
142
|
+
background-color: ${color.light.background.primary.default};
|
|
143
143
|
`,
|
|
144
144
|
[Theme.Dark]: css`
|
|
145
|
-
color: ${
|
|
145
|
+
color: ${color.dark.text.primary.default};
|
|
146
146
|
background-color: ${palette.gray.dark4};
|
|
147
|
-
border-color: ${palette.gray.base};
|
|
148
147
|
`,
|
|
149
148
|
};
|
|
150
149
|
|
|
@@ -160,29 +159,24 @@ export const comboboxSizeStyles = (
|
|
|
160
159
|
padding-right: ${comboboxPadding[size].xRight}px;
|
|
161
160
|
`;
|
|
162
161
|
|
|
163
|
-
export const
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
`,
|
|
170
|
-
[Theme.Dark]: css`
|
|
171
|
-
cursor: not-allowed;
|
|
172
|
-
color: ${palette.gray.dark1};
|
|
173
|
-
background-color: ${palette.gray.dark3};
|
|
174
|
-
border-color: ${palette.gray.dark2};
|
|
175
|
-
`,
|
|
176
|
-
};
|
|
162
|
+
export const getComboboxDisabledStyles = (theme: Theme) => css`
|
|
163
|
+
cursor: not-allowed;
|
|
164
|
+
color: ${color[theme].text.disabled.default};
|
|
165
|
+
background-color: ${color[theme].background.disabled.default};
|
|
166
|
+
border-color: ${color[theme].border.disabled.default};
|
|
167
|
+
`;
|
|
177
168
|
|
|
178
|
-
export const
|
|
179
|
-
[
|
|
180
|
-
border-color: ${
|
|
169
|
+
export const getComboboxStateStyles = (theme: Theme) => ({
|
|
170
|
+
[State.Error]: css`
|
|
171
|
+
border-color: ${color[theme].border.error.default};
|
|
181
172
|
`,
|
|
182
|
-
[
|
|
183
|
-
border-color: ${
|
|
173
|
+
[State.None]: css`
|
|
174
|
+
border-color: ${color[theme].border.primary.default};
|
|
184
175
|
`,
|
|
185
|
-
|
|
176
|
+
[State.Valid]: css`
|
|
177
|
+
border-color: ${color[theme].border.success.default};
|
|
178
|
+
`,
|
|
179
|
+
});
|
|
186
180
|
|
|
187
181
|
export const comboboxFocusStyle: Record<Theme, string> = {
|
|
188
182
|
[Theme.Light]: css`
|
|
@@ -206,16 +200,16 @@ export const iconsWrapperBaseStyles = css`
|
|
|
206
200
|
|
|
207
201
|
export const iconsWrapperSizeStyles: Record<Size, string> = {
|
|
208
202
|
[Size.XSmall]: css`
|
|
209
|
-
gap: ${spacing[
|
|
203
|
+
gap: ${spacing[100]}px;
|
|
210
204
|
`,
|
|
211
205
|
[Size.Small]: css`
|
|
212
|
-
gap: ${spacing[
|
|
206
|
+
gap: ${spacing[200]}px;
|
|
213
207
|
`,
|
|
214
208
|
[Size.Default]: css`
|
|
215
|
-
gap: ${spacing[
|
|
209
|
+
gap: ${spacing[200]}px;
|
|
216
210
|
`,
|
|
217
211
|
[Size.Large]: css`
|
|
218
|
-
gap: ${spacing[
|
|
212
|
+
gap: ${spacing[200]}px;
|
|
219
213
|
`,
|
|
220
214
|
};
|
|
221
215
|
|
|
@@ -291,7 +285,7 @@ export const baseInputElementStyle = css`
|
|
|
291
285
|
|
|
292
286
|
// Only add padding if there are chips
|
|
293
287
|
&:not(:first-child) {
|
|
294
|
-
padding-left: ${spacing[
|
|
288
|
+
padding-left: ${spacing[100]}px;
|
|
295
289
|
}
|
|
296
290
|
|
|
297
291
|
&:placeholder-shown {
|
|
@@ -305,12 +299,12 @@ export const baseInputElementStyle = css`
|
|
|
305
299
|
export const inputElementThemeStyle: Record<Theme, string> = {
|
|
306
300
|
[Theme.Light]: css`
|
|
307
301
|
&::placeholder {
|
|
308
|
-
color: ${palette.gray.
|
|
302
|
+
color: ${palette.gray.base};
|
|
309
303
|
}
|
|
310
304
|
`,
|
|
311
305
|
[Theme.Dark]: css`
|
|
312
306
|
&::placeholder {
|
|
313
|
-
color: ${palette.gray.
|
|
307
|
+
color: ${palette.gray.dark1};
|
|
314
308
|
}
|
|
315
309
|
`,
|
|
316
310
|
};
|
|
@@ -318,7 +312,7 @@ export const inputElementThemeStyle: Record<Theme, string> = {
|
|
|
318
312
|
export const inputElementDisabledThemeStyle: Record<Theme, string> = {
|
|
319
313
|
[Theme.Light]: css`
|
|
320
314
|
&::placeholder {
|
|
321
|
-
color: ${palette.gray.
|
|
315
|
+
color: ${palette.gray.base};
|
|
322
316
|
}
|
|
323
317
|
`,
|
|
324
318
|
[Theme.Dark]: css`
|
|
@@ -362,28 +356,13 @@ export const clearButtonStyle = css`
|
|
|
362
356
|
margin-inline: -6px;
|
|
363
357
|
`;
|
|
364
358
|
|
|
365
|
-
export const
|
|
359
|
+
export const iconStyle = css`
|
|
366
360
|
height: ${caretIconSize}px;
|
|
367
361
|
width: ${caretIconSize}px;
|
|
368
362
|
`;
|
|
369
363
|
|
|
370
|
-
export const errorMessageThemeStyle: Record<Theme, string> = {
|
|
371
|
-
[Theme.Light]: css`
|
|
372
|
-
color: ${palette.red.base};
|
|
373
|
-
`,
|
|
374
|
-
[Theme.Dark]: css`
|
|
375
|
-
color: ${palette.red.light1};
|
|
376
|
-
`,
|
|
377
|
-
};
|
|
378
|
-
|
|
379
|
-
export const errorMessageSizeStyle = (size: Size) => css`
|
|
380
|
-
font-size: ${fontSize[size]}px;
|
|
381
|
-
line-height: ${lineHeight[size]}px;
|
|
382
|
-
padding-top: ${comboboxPadding[size].y}px;
|
|
383
|
-
`;
|
|
384
|
-
|
|
385
364
|
export const labelDescriptionContainerStyle = css`
|
|
386
|
-
margin-bottom: ${spacing[
|
|
365
|
+
margin-bottom: ${spacing[100]}px;
|
|
387
366
|
display: flex;
|
|
388
367
|
flex-direction: column;
|
|
389
368
|
`;
|
|
@@ -407,17 +386,8 @@ export const comboboxOverflowShadowStyles: Record<Theme, string> = {
|
|
|
407
386
|
`,
|
|
408
387
|
};
|
|
409
388
|
|
|
410
|
-
export const
|
|
411
|
-
[
|
|
412
|
-
[Theme.Dark]: palette.red.light1,
|
|
413
|
-
};
|
|
389
|
+
export const getCaretIconFill = (theme: Theme) =>
|
|
390
|
+
color[theme].icon.primary.default;
|
|
414
391
|
|
|
415
|
-
export const
|
|
416
|
-
[
|
|
417
|
-
[Theme.Dark]: palette.gray.light1,
|
|
418
|
-
};
|
|
419
|
-
|
|
420
|
-
export const caretIconDisabledStyles: Record<Theme, string> = {
|
|
421
|
-
[Theme.Light]: palette.gray.base,
|
|
422
|
-
[Theme.Dark]: palette.gray.dark1,
|
|
423
|
-
};
|
|
392
|
+
export const getCaretIconDisabledFill = (theme: Theme) =>
|
|
393
|
+
color[theme].icon.disabled.default;
|
|
@@ -21,6 +21,7 @@ import isUndefined from 'lodash/isUndefined';
|
|
|
21
21
|
import PropTypes from 'prop-types';
|
|
22
22
|
|
|
23
23
|
import { cx } from '@leafygreen-ui/emotion';
|
|
24
|
+
import { DEFAULT_MESSAGES, FormFieldFeedback } from '@leafygreen-ui/form-field';
|
|
24
25
|
import {
|
|
25
26
|
useAutoScroll,
|
|
26
27
|
useBackdropClick,
|
|
@@ -68,20 +69,17 @@ import { isValueCurrentSelection } from './utils/isValueCurrentSelection';
|
|
|
68
69
|
import {
|
|
69
70
|
baseComboboxStyles,
|
|
70
71
|
baseInputElementStyle,
|
|
71
|
-
caretIconDisabledStyles,
|
|
72
|
-
caretIconThemeStyles,
|
|
73
72
|
clearButtonStyle,
|
|
74
|
-
comboboxDisabledStyles,
|
|
75
|
-
comboboxErrorStyles,
|
|
76
73
|
comboboxFocusStyle,
|
|
77
74
|
comboboxOverflowShadowStyles,
|
|
78
75
|
comboboxParentStyle,
|
|
79
76
|
comboboxSizeStyles,
|
|
80
77
|
comboboxThemeStyles,
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
78
|
+
getCaretIconDisabledFill,
|
|
79
|
+
getCaretIconFill,
|
|
80
|
+
getComboboxDisabledStyles,
|
|
81
|
+
getComboboxStateStyles,
|
|
82
|
+
iconStyle,
|
|
85
83
|
iconsWrapperBaseStyles,
|
|
86
84
|
iconsWrapperSizeStyles,
|
|
87
85
|
inputElementDisabledThemeStyle,
|
|
@@ -110,7 +108,8 @@ export function Combobox<M extends boolean>({
|
|
|
110
108
|
size = ComboboxSize.Default,
|
|
111
109
|
darkMode: darkModeProp,
|
|
112
110
|
state = 'none',
|
|
113
|
-
errorMessage,
|
|
111
|
+
errorMessage = DEFAULT_MESSAGES.error,
|
|
112
|
+
successMessage = DEFAULT_MESSAGES.success,
|
|
114
113
|
searchState = 'unset',
|
|
115
114
|
searchEmptyMessage = 'No results found',
|
|
116
115
|
searchErrorMessage = 'Could not get results!',
|
|
@@ -1166,6 +1165,14 @@ export function Combobox<M extends boolean>({
|
|
|
1166
1165
|
: { usePortal }),
|
|
1167
1166
|
} as const;
|
|
1168
1167
|
|
|
1168
|
+
const formFieldFeedbackProps = {
|
|
1169
|
+
disabled,
|
|
1170
|
+
errorMessage,
|
|
1171
|
+
size,
|
|
1172
|
+
state,
|
|
1173
|
+
successMessage,
|
|
1174
|
+
} as const;
|
|
1175
|
+
|
|
1169
1176
|
return (
|
|
1170
1177
|
<LeafyGreenProvider darkMode={darkMode}>
|
|
1171
1178
|
<ComboboxContext.Provider
|
|
@@ -1232,12 +1239,12 @@ export function Combobox<M extends boolean>({
|
|
|
1232
1239
|
baseComboboxStyles,
|
|
1233
1240
|
comboboxThemeStyles[theme],
|
|
1234
1241
|
comboboxSizeStyles(size, isMultiselectWithSelections),
|
|
1242
|
+
getComboboxStateStyles(theme)[state],
|
|
1235
1243
|
{
|
|
1236
|
-
[comboboxDisabledStyles[theme]]: disabled,
|
|
1237
|
-
[comboboxErrorStyles[theme]]: state === State.error,
|
|
1238
1244
|
[comboboxFocusStyle[theme]]: isElementFocused(
|
|
1239
1245
|
ComboboxElement.Input,
|
|
1240
1246
|
),
|
|
1247
|
+
[getComboboxDisabledStyles(theme)]: disabled,
|
|
1241
1248
|
[comboboxOverflowShadowStyles[theme]]: shouldShowOverflowShadow,
|
|
1242
1249
|
},
|
|
1243
1250
|
)}
|
|
@@ -1270,7 +1277,8 @@ export function Combobox<M extends boolean>({
|
|
|
1270
1277
|
},
|
|
1271
1278
|
)}
|
|
1272
1279
|
placeholder={placeholderValue}
|
|
1273
|
-
disabled={disabled
|
|
1280
|
+
aria-disabled={disabled}
|
|
1281
|
+
readOnly={disabled}
|
|
1274
1282
|
onChange={handleInputChange}
|
|
1275
1283
|
value={inputValue}
|
|
1276
1284
|
autoComplete="off"
|
|
@@ -1282,17 +1290,9 @@ export function Combobox<M extends boolean>({
|
|
|
1282
1290
|
iconsWrapperSizeStyles[size],
|
|
1283
1291
|
)}
|
|
1284
1292
|
>
|
|
1285
|
-
{state === 'error' && (
|
|
1286
|
-
<Icon
|
|
1287
|
-
glyph="Warning"
|
|
1288
|
-
fill={errorIconThemeStyles[theme]}
|
|
1289
|
-
className={endIconStyle}
|
|
1290
|
-
/>
|
|
1291
|
-
)}
|
|
1292
1293
|
{clearable && doesSelectionExist(selection) && !disabled && (
|
|
1293
1294
|
<IconButton
|
|
1294
1295
|
aria-label="Clear selection"
|
|
1295
|
-
aria-disabled={disabled}
|
|
1296
1296
|
disabled={disabled}
|
|
1297
1297
|
ref={clearButtonRef}
|
|
1298
1298
|
onClick={handleClearButtonClick}
|
|
@@ -1305,25 +1305,15 @@ export function Combobox<M extends boolean>({
|
|
|
1305
1305
|
)}
|
|
1306
1306
|
<Icon
|
|
1307
1307
|
glyph="CaretDown"
|
|
1308
|
-
className={
|
|
1308
|
+
className={iconStyle}
|
|
1309
1309
|
fill={cx({
|
|
1310
|
-
[
|
|
1311
|
-
[
|
|
1310
|
+
[getCaretIconFill(theme)]: !disabled,
|
|
1311
|
+
[getCaretIconDisabledFill(theme)]: disabled,
|
|
1312
1312
|
})}
|
|
1313
1313
|
/>
|
|
1314
1314
|
</div>
|
|
1315
1315
|
</div>
|
|
1316
|
-
|
|
1317
|
-
{state === 'error' && errorMessage && (
|
|
1318
|
-
<div
|
|
1319
|
-
className={cx(
|
|
1320
|
-
errorMessageThemeStyle[theme],
|
|
1321
|
-
errorMessageSizeStyle(size),
|
|
1322
|
-
)}
|
|
1323
|
-
>
|
|
1324
|
-
{errorMessage}
|
|
1325
|
-
</div>
|
|
1326
|
-
)}
|
|
1316
|
+
<FormFieldFeedback {...formFieldFeedbackProps} />
|
|
1327
1317
|
|
|
1328
1318
|
{/******* /
|
|
1329
1319
|
* Menu *
|
|
@@ -110,7 +110,12 @@ export type BaseComboboxProps = Omit<HTMLElementProps<'div'>, 'onChange'> &
|
|
|
110
110
|
/**
|
|
111
111
|
* The message shown below the input when state is `error`
|
|
112
112
|
*/
|
|
113
|
-
errorMessage?:
|
|
113
|
+
errorMessage?: ReactNode;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* The message shown below the input when state is `valid`
|
|
117
|
+
*/
|
|
118
|
+
successMessage?: ReactNode;
|
|
114
119
|
|
|
115
120
|
/**
|
|
116
121
|
* The state of search results. Toggles search messages within the menu.
|
package/src/Combobox.stories.tsx
CHANGED
|
@@ -118,11 +118,11 @@ const meta: StoryMetaType<typeof Combobox> = {
|
|
|
118
118
|
},
|
|
119
119
|
searchErrorMessage: {
|
|
120
120
|
control: 'text',
|
|
121
|
-
if: { arg: 'searchState', eq: SearchState.
|
|
121
|
+
if: { arg: 'searchState', eq: SearchState.Error },
|
|
122
122
|
},
|
|
123
123
|
searchLoadingMessage: {
|
|
124
124
|
control: 'text',
|
|
125
|
-
if: { arg: 'searchState', eq: SearchState.
|
|
125
|
+
if: { arg: 'searchState', eq: SearchState.Loading },
|
|
126
126
|
},
|
|
127
127
|
chipTruncationLocation: {
|
|
128
128
|
options: Object.values(TruncationLocation),
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { FormFieldState } from '@leafygreen-ui/form-field';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Identifier for individual component elements within the Combobox
|
|
3
5
|
*/
|
|
@@ -43,18 +45,15 @@ export const Overflow = {
|
|
|
43
45
|
} as const;
|
|
44
46
|
export type Overflow = (typeof Overflow)[keyof typeof Overflow];
|
|
45
47
|
|
|
46
|
-
/** The error state of the Combobox */
|
|
47
|
-
export const State =
|
|
48
|
-
none: 'none',
|
|
49
|
-
error: 'error',
|
|
50
|
-
} as const;
|
|
48
|
+
/** The error/valid state of the Combobox */
|
|
49
|
+
export const State = FormFieldState;
|
|
51
50
|
export type State = (typeof State)[keyof typeof State];
|
|
52
51
|
|
|
53
52
|
/** The search state of the Combobox */
|
|
54
53
|
export const SearchState = {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
Unset: 'unset',
|
|
55
|
+
Error: 'error',
|
|
56
|
+
Loading: 'loading',
|
|
58
57
|
} as const;
|
|
59
58
|
export type SearchState = (typeof SearchState)[keyof typeof SearchState];
|
|
60
59
|
|