@leafygreen-ui/combobox 5.0.7 → 5.0.9
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 +22 -0
- package/dist/{Chip.d.ts → Chip/Chip.d.ts} +1 -1
- package/dist/Chip/Chip.d.ts.map +1 -0
- package/dist/Chip/Chip.styles.d.ts +23 -0
- package/dist/Chip/Chip.styles.d.ts.map +1 -0
- package/dist/Chip/index.d.ts +2 -0
- package/dist/Chip/index.d.ts.map +1 -0
- package/dist/{Combobox.d.ts → Combobox/Combobox.d.ts} +1 -1
- package/dist/Combobox/Combobox.d.ts.map +1 -0
- package/dist/{Combobox.styles.d.ts → Combobox/Combobox.styles.d.ts} +1 -12
- package/dist/Combobox/Combobox.styles.d.ts.map +1 -0
- package/dist/Combobox/index.d.ts +2 -0
- package/dist/Combobox/index.d.ts.map +1 -0
- package/dist/Combobox.types.d.ts +3 -3
- package/dist/Combobox.types.d.ts.map +1 -1
- package/dist/{ComboboxContext.d.ts → ComboboxContext/ComboboxContext.d.ts} +1 -4
- package/dist/ComboboxContext/ComboboxContext.d.ts.map +1 -0
- package/dist/ComboboxContext/index.d.ts +2 -0
- package/dist/ComboboxContext/index.d.ts.map +1 -0
- package/dist/{ComboboxGroup.d.ts → ComboboxGroup/ComboboxGroup.d.ts} +3 -4
- package/dist/ComboboxGroup/ComboboxGroup.d.ts.map +1 -0
- package/dist/ComboboxGroup/ComboboxGroup.styles.d.ts +5 -0
- package/dist/ComboboxGroup/ComboboxGroup.styles.d.ts.map +1 -0
- package/dist/ComboboxGroup/index.d.ts +2 -0
- package/dist/ComboboxGroup/index.d.ts.map +1 -0
- package/dist/ComboboxMenu/ComboboxMenu.d.ts.map +1 -1
- package/dist/ComboboxMenu/index.d.ts +2 -0
- package/dist/ComboboxMenu/index.d.ts.map +1 -0
- package/dist/{ComboboxOption.d.ts → ComboboxOption/ComboboxOption.d.ts} +5 -4
- package/dist/ComboboxOption/ComboboxOption.d.ts.map +1 -0
- package/dist/ComboboxOption/ComboboxOption.styles.d.ts +11 -0
- package/dist/ComboboxOption/ComboboxOption.styles.d.ts.map +1 -0
- package/dist/ComboboxOption/OptionContent.d.ts +4 -0
- package/dist/ComboboxOption/OptionContent.d.ts.map +1 -0
- package/dist/ComboboxOption/index.d.ts +2 -0
- package/dist/ComboboxOption/index.d.ts.map +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/{ComboboxTestUtils.d.ts → utils/ComboboxTestUtils.d.ts} +1 -1
- package/dist/utils/ComboboxTestUtils.d.ts.map +1 -0
- package/package.json +9 -8
- package/src/Chip/Chip.styles.ts +150 -0
- package/src/{Chip.tsx → Chip/Chip.tsx} +18 -138
- package/src/Chip/index.ts +1 -0
- package/src/{Combobox.spec.tsx → Combobox/Combobox.spec.tsx} +72 -15
- package/src/{Combobox.story.tsx → Combobox/Combobox.story.tsx} +7 -18
- package/src/{Combobox.styles.ts → Combobox/Combobox.styles.ts} +5 -19
- package/src/{Combobox.tsx → Combobox/Combobox.tsx} +196 -260
- package/src/Combobox/index.ts +1 -0
- package/src/Combobox.types.ts +4 -3
- package/src/{ComboboxContext.tsx → ComboboxContext/ComboboxContext.tsx} +1 -7
- package/src/ComboboxContext/index.ts +1 -0
- package/src/ComboboxGroup/ComboboxGroup.styles.ts +34 -0
- package/src/ComboboxGroup/ComboboxGroup.tsx +53 -0
- package/src/ComboboxGroup/index.ts +1 -0
- package/src/ComboboxMenu/ComboboxMenu.tsx +3 -2
- package/src/ComboboxMenu/index.ts +1 -0
- package/src/ComboboxOption/ComboboxOption.styles.ts +68 -0
- package/src/ComboboxOption/ComboboxOption.tsx +107 -0
- package/src/ComboboxOption/OptionContent.tsx +87 -0
- package/src/ComboboxOption/index.ts +1 -0
- package/src/index.ts +1 -1
- package/src/{ComboboxTestUtils.tsx → utils/ComboboxTestUtils.tsx} +3 -2
- package/tsconfig.json +3 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/tsdoc.json +543 -3
- package/dist/Chip.d.ts.map +0 -1
- package/dist/Combobox.d.ts.map +0 -1
- package/dist/Combobox.styles.d.ts.map +0 -1
- package/dist/ComboboxContext.d.ts.map +0 -1
- package/dist/ComboboxGroup.d.ts.map +0 -1
- package/dist/ComboboxOption.d.ts.map +0 -1
- package/dist/ComboboxTestUtils.d.ts.map +0 -1
- package/dist/Menu.styles.d.ts +0 -22
- package/dist/Menu.styles.d.ts.map +0 -1
- package/src/ComboboxGroup.tsx +0 -80
- package/src/ComboboxOption.tsx +0 -327
- package/src/Menu.styles.ts +0 -112
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="jest" />
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { BaseComboboxProps, ComboboxMultiselectProps, OptionObject } from '
|
|
3
|
+
import { BaseComboboxProps, ComboboxMultiselectProps, OptionObject } from '../Combobox.types';
|
|
4
4
|
export interface NestedObject {
|
|
5
5
|
label: string;
|
|
6
6
|
children: Array<string | OptionObject>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComboboxTestUtils.d.ts","sourceRoot":"","sources":["../../src/utils/ComboboxTestUtils.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAgB1B,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,YAAY,EACb,MAAM,mBAAmB,CAAC;AAG3B,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC,MAAM,GAAG,YAAY,CAAC,CAAC;CACxC;AAED,oBAAY,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;AAC3C,aAAK,mBAAmB,GAAG;IACzB,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,YAAY,GAAG,YAAY,CAAC,CAAC;CACvD,GAAG,iBAAiB,GACnB,wBAAwB,CAAC,OAAO,CAAC,CAAC;AAEpC,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,YAAY,CAgB9C,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,YAAY,CA+B9C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,0DA4C1B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAC7C,MAAM,GAAE,CAAiB,EACzB,KAAK,CAAC,EAAE,mBAAmB;iCAsDS,mBAAmB;;gBAetB,MAAM,GAAG,WAAW,GAAG,IAAI;gBAC3B,MAAM,MAAM,CAAC,GAAG,MAAM,WAAW,CAAC,GAAG,IAAI;;;gBAgBxC,MAAM,GAAG,WAAW,GAAG,IAAI;gBAC3B,OAAO,GAAG,MAAM,GAAG,WAAW,GAAG,IAAI;gBACrC,MAAM,MAAM,CAAC,GAAG,MAAM,WAAW,CAAC,GAAG,IAAI;;yBA5BjD,MAAM,WAAW,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6D7C;AAED;;;;GAIG;AACH,eAAO,MAAM,MAAM,cAAe,OAAO,YAAmC,CAAC;AAiC7E,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,IAAI,CAAC;QACb,UAAU,QAAQ,CAAC,CAAC;YAClB,cAAc,IAAI,CAAC,CAAC;SACrB;KACF;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leafygreen-ui/combobox",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.9",
|
|
4
4
|
"description": "leafyGreen UI Kit Combobox",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -20,26 +20,27 @@
|
|
|
20
20
|
"access": "public"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@leafygreen-ui/checkbox": "^12.0.
|
|
23
|
+
"@leafygreen-ui/checkbox": "^12.0.6",
|
|
24
24
|
"@leafygreen-ui/emotion": "^4.0.3",
|
|
25
|
-
"@leafygreen-ui/hooks": "^7.
|
|
25
|
+
"@leafygreen-ui/hooks": "^7.6.0",
|
|
26
26
|
"@leafygreen-ui/icon": "^11.12.4",
|
|
27
|
-
"@leafygreen-ui/icon-button": "^15.0.
|
|
27
|
+
"@leafygreen-ui/icon-button": "^15.0.6",
|
|
28
28
|
"@leafygreen-ui/inline-definition": "^6.0.2",
|
|
29
|
-
"@leafygreen-ui/
|
|
29
|
+
"@leafygreen-ui/input-option": "^1.0.0",
|
|
30
|
+
"@leafygreen-ui/lib": "^10.2.1",
|
|
30
31
|
"@leafygreen-ui/palette": "^3.4.7",
|
|
31
32
|
"@leafygreen-ui/popover": "^11.0.5",
|
|
32
33
|
"@leafygreen-ui/tokens": "^2.0.0",
|
|
33
|
-
"@leafygreen-ui/typography": "^16.0.
|
|
34
|
+
"@leafygreen-ui/typography": "^16.0.1",
|
|
34
35
|
"chalk": "^4.1.2",
|
|
35
36
|
"lodash": "^4.17.21",
|
|
36
37
|
"polished": "^4.2.2"
|
|
37
38
|
},
|
|
38
39
|
"peerDependencies": {
|
|
39
|
-
"@leafygreen-ui/leafygreen-provider": "^3.1.
|
|
40
|
+
"@leafygreen-ui/leafygreen-provider": "^3.1.1"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
|
-
"@leafygreen-ui/button": "^
|
|
43
|
+
"@leafygreen-ui/button": "^20.0.1"
|
|
43
44
|
},
|
|
44
45
|
"homepage": "https://github.com/mongodb/leafygreen-ui/tree/main/packages/combobox",
|
|
45
46
|
"repository": {
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { css } from '@leafygreen-ui/emotion';
|
|
2
|
+
import { Theme } from '@leafygreen-ui/lib';
|
|
3
|
+
import { palette } from '@leafygreen-ui/palette';
|
|
4
|
+
import { transitionDuration, typeScales } from '@leafygreen-ui/tokens';
|
|
5
|
+
|
|
6
|
+
import { ComboboxSize } from '../Combobox.types';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Vertical padding on a chip (in px)
|
|
10
|
+
*/
|
|
11
|
+
export const chipWrapperPaddingY = {
|
|
12
|
+
[ComboboxSize.Default]: 2,
|
|
13
|
+
[ComboboxSize.Large]: 4,
|
|
14
|
+
} as const;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Height of the chip element (in px)
|
|
18
|
+
*/
|
|
19
|
+
export const chipHeight: Record<ComboboxSize, number> = {
|
|
20
|
+
[ComboboxSize.Default]:
|
|
21
|
+
typeScales.body1.lineHeight + 2 * chipWrapperPaddingY[ComboboxSize.Default], // 20
|
|
22
|
+
[ComboboxSize.Large]:
|
|
23
|
+
typeScales.body2.lineHeight + 2 * chipWrapperPaddingY[ComboboxSize.Large], // 28
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const chipWrapperBaseStyle = css`
|
|
27
|
+
display: inline-flex;
|
|
28
|
+
align-items: center;
|
|
29
|
+
overflow: hidden;
|
|
30
|
+
white-space: nowrap;
|
|
31
|
+
box-sizing: border-box;
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
export const chipWrapperSizeStyle: Record<ComboboxSize, string> = {
|
|
35
|
+
[ComboboxSize.Default]: css`
|
|
36
|
+
font-size: ${typeScales.body1.fontSize}px;
|
|
37
|
+
line-height: ${typeScales.body1.lineHeight}px;
|
|
38
|
+
border-radius: 4px;
|
|
39
|
+
`,
|
|
40
|
+
[ComboboxSize.Large]: css`
|
|
41
|
+
font-size: ${typeScales.body2.fontSize}px;
|
|
42
|
+
line-height: ${typeScales.body2.lineHeight}px;
|
|
43
|
+
border-radius: 4px;
|
|
44
|
+
`,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const chipWrapperThemeStyle: Record<Theme, string> = {
|
|
48
|
+
[Theme.Light]: css`
|
|
49
|
+
color: ${palette.black};
|
|
50
|
+
background-color: ${palette.gray.light2};
|
|
51
|
+
|
|
52
|
+
// TODO: - refine these styles with Design
|
|
53
|
+
&:focus-within {
|
|
54
|
+
background-color: ${palette.blue.light2};
|
|
55
|
+
}
|
|
56
|
+
`,
|
|
57
|
+
[Theme.Dark]: css`
|
|
58
|
+
color: ${palette.gray.light2};
|
|
59
|
+
background-color: ${palette.gray.dark2};
|
|
60
|
+
|
|
61
|
+
&:focus-within {
|
|
62
|
+
background-color: ${palette.blue.dark2};
|
|
63
|
+
}
|
|
64
|
+
`,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const disabledChipWrapperStyle: Record<Theme, string> = {
|
|
68
|
+
[Theme.Light]: css`
|
|
69
|
+
cursor: not-allowed;
|
|
70
|
+
color: ${palette.gray.base};
|
|
71
|
+
background-color: ${palette.gray.light3};
|
|
72
|
+
`,
|
|
73
|
+
[Theme.Dark]: css`
|
|
74
|
+
cursor: not-allowed;
|
|
75
|
+
color: ${palette.gray.dark2};
|
|
76
|
+
background-color: ${palette.gray.dark4};
|
|
77
|
+
box-shadow: inset 0 0 1px 1px ${palette.gray.dark2}; ;
|
|
78
|
+
`,
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const chipTextSizeStyle: Record<ComboboxSize, string> = {
|
|
82
|
+
[ComboboxSize.Default]: css`
|
|
83
|
+
padding-inline: 6px;
|
|
84
|
+
padding-block: ${chipWrapperPaddingY[ComboboxSize.Default]}px;
|
|
85
|
+
`,
|
|
86
|
+
[ComboboxSize.Large]: css`
|
|
87
|
+
padding-inline: 10px;
|
|
88
|
+
padding-block: ${chipWrapperPaddingY[ComboboxSize.Large]}px;
|
|
89
|
+
`,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export const chipButtonStyle = css`
|
|
93
|
+
position: relative;
|
|
94
|
+
display: flex;
|
|
95
|
+
align-items: center;
|
|
96
|
+
justify-content: center;
|
|
97
|
+
width: 100%;
|
|
98
|
+
outline: none;
|
|
99
|
+
border: none;
|
|
100
|
+
background-color: transparent;
|
|
101
|
+
cursor: pointer;
|
|
102
|
+
transition: background-color ${transitionDuration.faster}ms ease-in-out;
|
|
103
|
+
`;
|
|
104
|
+
|
|
105
|
+
export const chipButtonSizeStyle: Record<ComboboxSize, string> = {
|
|
106
|
+
[ComboboxSize.Default]: css`
|
|
107
|
+
height: ${chipHeight[ComboboxSize.Default]}px;
|
|
108
|
+
`,
|
|
109
|
+
[ComboboxSize.Large]: css`
|
|
110
|
+
height: ${chipHeight[ComboboxSize.Large]}px;
|
|
111
|
+
`,
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export const chipButtonThemeStyle: Record<Theme, string> = {
|
|
115
|
+
[Theme.Light]: css`
|
|
116
|
+
color: ${palette.gray.dark2};
|
|
117
|
+
|
|
118
|
+
&:hover {
|
|
119
|
+
color: ${palette.black};
|
|
120
|
+
background-color: ${palette.gray.light1};
|
|
121
|
+
}
|
|
122
|
+
`,
|
|
123
|
+
[Theme.Dark]: css`
|
|
124
|
+
color: ${palette.gray.light1};
|
|
125
|
+
|
|
126
|
+
&:hover {
|
|
127
|
+
color: ${palette.gray.light3};
|
|
128
|
+
background-color: ${palette.gray.dark1};
|
|
129
|
+
}
|
|
130
|
+
`,
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export const chipButtonDisabledStyle: Record<Theme, string> = {
|
|
134
|
+
[Theme.Light]: css`
|
|
135
|
+
cursor: not-allowed;
|
|
136
|
+
color: ${palette.gray.dark2};
|
|
137
|
+
&:hover {
|
|
138
|
+
color: inherit;
|
|
139
|
+
background-color: unset;
|
|
140
|
+
}
|
|
141
|
+
`,
|
|
142
|
+
[Theme.Dark]: css`
|
|
143
|
+
cursor: not-allowed;
|
|
144
|
+
color: ${palette.gray.dark2};
|
|
145
|
+
&:hover {
|
|
146
|
+
color: inherit;
|
|
147
|
+
background-color: unset;
|
|
148
|
+
}
|
|
149
|
+
`,
|
|
150
|
+
};
|
|
@@ -1,151 +1,31 @@
|
|
|
1
1
|
import React, { useContext, useEffect, useMemo, useRef } from 'react';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { cx } from '@leafygreen-ui/emotion';
|
|
4
4
|
import Icon from '@leafygreen-ui/icon';
|
|
5
5
|
import InlineDefinition from '@leafygreen-ui/inline-definition';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { transitionDuration, typeScales } from '@leafygreen-ui/tokens';
|
|
6
|
+
import { useDarkMode } from '@leafygreen-ui/leafygreen-provider';
|
|
7
|
+
import { keyMap } from '@leafygreen-ui/lib';
|
|
9
8
|
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
inputHeight,
|
|
14
|
-
} from './Combobox.styles';
|
|
15
|
-
import { ChipProps, ComboboxSize as Size } from './Combobox.types';
|
|
16
|
-
import { ComboboxContext } from './ComboboxContext';
|
|
17
|
-
|
|
18
|
-
const chipWrapperBaseStyle = css`
|
|
19
|
-
display: inline-flex;
|
|
20
|
-
align-items: center;
|
|
21
|
-
overflow: hidden;
|
|
22
|
-
white-space: nowrap;
|
|
23
|
-
box-sizing: border-box;
|
|
24
|
-
`;
|
|
25
|
-
|
|
26
|
-
const chipWrapperSizeStyle: Record<Size, string> = {
|
|
27
|
-
[Size.Default]: css`
|
|
28
|
-
font-size: ${typeScales.body1.fontSize}px;
|
|
29
|
-
line-height: ${typeScales.body1.lineHeight}px;
|
|
30
|
-
border-radius: 4px;
|
|
31
|
-
`,
|
|
32
|
-
[Size.Large]: css`
|
|
33
|
-
font-size: ${typeScales.body2.fontSize}px;
|
|
34
|
-
line-height: ${typeScales.body2.lineHeight}px;
|
|
35
|
-
border-radius: 4px;
|
|
36
|
-
`,
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const chipWrapperThemeStyle: Record<Theme, string> = {
|
|
40
|
-
[Theme.Light]: css`
|
|
41
|
-
color: ${palette.black};
|
|
42
|
-
background-color: ${palette.gray.light2};
|
|
43
|
-
|
|
44
|
-
// TODO: - refine these styles with Design
|
|
45
|
-
&:focus-within {
|
|
46
|
-
background-color: ${palette.blue.light2};
|
|
47
|
-
}
|
|
48
|
-
`,
|
|
49
|
-
[Theme.Dark]: css`
|
|
50
|
-
color: ${palette.gray.light2};
|
|
51
|
-
background-color: ${palette.gray.dark2};
|
|
52
|
-
|
|
53
|
-
&:focus-within {
|
|
54
|
-
background-color: ${palette.blue.dark2};
|
|
55
|
-
}
|
|
56
|
-
`,
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const disabledChipWrapperStyle: Record<Theme, string> = {
|
|
60
|
-
[Theme.Light]: css`
|
|
61
|
-
cursor: not-allowed;
|
|
62
|
-
color: ${palette.gray.base};
|
|
63
|
-
background-color: ${palette.gray.light3};
|
|
64
|
-
`,
|
|
65
|
-
[Theme.Dark]: css`
|
|
66
|
-
cursor: not-allowed;
|
|
67
|
-
color: ${palette.gray.dark2};
|
|
68
|
-
background-color: ${palette.gray.dark4};
|
|
69
|
-
box-shadow: inset 0 0 1px 1px ${palette.gray.dark2}; ;
|
|
70
|
-
`,
|
|
71
|
-
};
|
|
9
|
+
import { ChipProps } from '../Combobox.types';
|
|
10
|
+
import { chipClassName } from '../Combobox/Combobox.styles';
|
|
11
|
+
import { ComboboxContext } from '../ComboboxContext';
|
|
72
12
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const chipButtonStyle = css`
|
|
85
|
-
position: relative;
|
|
86
|
-
display: flex;
|
|
87
|
-
align-items: center;
|
|
88
|
-
justify-content: center;
|
|
89
|
-
width: 100%;
|
|
90
|
-
outline: none;
|
|
91
|
-
border: none;
|
|
92
|
-
background-color: transparent;
|
|
93
|
-
cursor: pointer;
|
|
94
|
-
transition: background-color ${transitionDuration.faster}ms ease-in-out;
|
|
95
|
-
`;
|
|
96
|
-
|
|
97
|
-
const chipButtonSizeStyle: Record<Size, string> = {
|
|
98
|
-
[Size.Default]: css`
|
|
99
|
-
height: ${inputHeight[Size.Default]}px;
|
|
100
|
-
`,
|
|
101
|
-
[Size.Large]: css`
|
|
102
|
-
height: ${inputHeight[Size.Large]}px;
|
|
103
|
-
`,
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
const chipButtonThemeStyle: Record<Theme, string> = {
|
|
107
|
-
[Theme.Light]: css`
|
|
108
|
-
color: ${palette.gray.dark2};
|
|
109
|
-
|
|
110
|
-
&:hover {
|
|
111
|
-
color: ${palette.black};
|
|
112
|
-
background-color: ${palette.gray.light1};
|
|
113
|
-
}
|
|
114
|
-
`,
|
|
115
|
-
[Theme.Dark]: css`
|
|
116
|
-
color: ${palette.gray.light1};
|
|
117
|
-
|
|
118
|
-
&:hover {
|
|
119
|
-
color: ${palette.gray.light3};
|
|
120
|
-
background-color: ${palette.gray.dark1};
|
|
121
|
-
}
|
|
122
|
-
`,
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
const chipButtonDisabledStyle: Record<Theme, string> = {
|
|
126
|
-
[Theme.Light]: css`
|
|
127
|
-
cursor: not-allowed;
|
|
128
|
-
color: ${palette.gray.dark2};
|
|
129
|
-
&:hover {
|
|
130
|
-
color: inherit;
|
|
131
|
-
background-color: unset;
|
|
132
|
-
}
|
|
133
|
-
`,
|
|
134
|
-
[Theme.Dark]: css`
|
|
135
|
-
cursor: not-allowed;
|
|
136
|
-
color: ${palette.gray.dark2};
|
|
137
|
-
&:hover {
|
|
138
|
-
color: inherit;
|
|
139
|
-
background-color: unset;
|
|
140
|
-
}
|
|
141
|
-
`,
|
|
142
|
-
};
|
|
13
|
+
import {
|
|
14
|
+
chipButtonDisabledStyle,
|
|
15
|
+
chipButtonSizeStyle,
|
|
16
|
+
chipButtonStyle,
|
|
17
|
+
chipButtonThemeStyle,
|
|
18
|
+
chipTextSizeStyle,
|
|
19
|
+
chipWrapperBaseStyle,
|
|
20
|
+
chipWrapperSizeStyle,
|
|
21
|
+
chipWrapperThemeStyle,
|
|
22
|
+
disabledChipWrapperStyle,
|
|
23
|
+
} from './Chip.styles';
|
|
143
24
|
|
|
144
25
|
export const Chip = React.forwardRef<HTMLSpanElement, ChipProps>(
|
|
145
26
|
({ displayName, isFocused, onRemove, onFocus }: ChipProps, forwardedRef) => {
|
|
27
|
+
const { darkMode, theme } = useDarkMode();
|
|
146
28
|
const {
|
|
147
|
-
darkMode,
|
|
148
|
-
theme,
|
|
149
29
|
size,
|
|
150
30
|
disabled,
|
|
151
31
|
chipTruncationLocation = 'end',
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Chip } from './Chip';
|
|
@@ -18,7 +18,7 @@ import startCase from 'lodash/startCase';
|
|
|
18
18
|
import Button from '@leafygreen-ui/button';
|
|
19
19
|
import { keyMap } from '@leafygreen-ui/lib';
|
|
20
20
|
|
|
21
|
-
import { OptionObject } from '
|
|
21
|
+
import { OptionObject } from '../Combobox.types';
|
|
22
22
|
import {
|
|
23
23
|
defaultOptions,
|
|
24
24
|
getComboboxJSX,
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
renderCombobox,
|
|
28
28
|
Select,
|
|
29
29
|
testif,
|
|
30
|
-
} from '
|
|
30
|
+
} from '../utils/ComboboxTestUtils';
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* Tests
|
|
@@ -145,6 +145,14 @@ describe('packages/combobox', () => {
|
|
|
145
145
|
expect(optionElements).toHaveLength(defaultOptions.length);
|
|
146
146
|
});
|
|
147
147
|
|
|
148
|
+
test('option accepts data attribute', () => {
|
|
149
|
+
const { openMenu } = renderCombobox(select);
|
|
150
|
+
const { optionElements } = openMenu();
|
|
151
|
+
expect(optionElements?.[0].getAttribute('data-testid')).toBe(
|
|
152
|
+
defaultOptions[0].value,
|
|
153
|
+
);
|
|
154
|
+
});
|
|
155
|
+
|
|
148
156
|
test('Options render with provided displayName', async () => {
|
|
149
157
|
const { openMenu } = renderCombobox(select);
|
|
150
158
|
const { optionElements } = openMenu();
|
|
@@ -285,9 +293,10 @@ describe('packages/combobox', () => {
|
|
|
285
293
|
expect(document.body).toHaveFocus();
|
|
286
294
|
});
|
|
287
295
|
|
|
296
|
+
// TODO: Fix this test. Combobox SHOULD be focusable
|
|
288
297
|
test('Combobox is not focusable when `disabled`', () => {
|
|
289
298
|
renderCombobox(select, { disabled: true });
|
|
290
|
-
userEvent.type(document.body, '{tab');
|
|
299
|
+
userEvent.type(document.body, '{tab}');
|
|
291
300
|
expect(document.body).toHaveFocus();
|
|
292
301
|
});
|
|
293
302
|
});
|
|
@@ -1033,6 +1042,10 @@ describe('packages/combobox', () => {
|
|
|
1033
1042
|
expect(highlight).toHaveTextContent('Banana');
|
|
1034
1043
|
});
|
|
1035
1044
|
|
|
1045
|
+
test.todo('Down arrow cycles highlight to top');
|
|
1046
|
+
|
|
1047
|
+
test.todo('Up arrow cycles highlight to bottom');
|
|
1048
|
+
|
|
1036
1049
|
test('Down arrow key opens menu when its closed', async () => {
|
|
1037
1050
|
const { inputEl, openMenu, findByRole } = renderCombobox(select);
|
|
1038
1051
|
const { menuContainerEl } = openMenu();
|
|
@@ -1099,15 +1112,14 @@ describe('packages/combobox', () => {
|
|
|
1099
1112
|
waitFor(() => expect(inputEl).toHaveFocus());
|
|
1100
1113
|
});
|
|
1101
1114
|
|
|
1102
|
-
|
|
1103
|
-
test.skip('When focus is on clear button, Left arrow moves focus to input', async () => {
|
|
1115
|
+
test('When focus is on clear button, Left arrow moves focus to input', async () => {
|
|
1104
1116
|
const initialValue = select === 'multiple' ? ['apple'] : 'apple';
|
|
1105
1117
|
const { inputEl } = renderCombobox(select, {
|
|
1106
1118
|
initialValue,
|
|
1107
1119
|
});
|
|
1108
1120
|
userEvent.type(inputEl!, '{arrowright}{arrowleft}');
|
|
1109
1121
|
expect(inputEl!).toHaveFocus();
|
|
1110
|
-
expect(inputEl!.selectionEnd).toEqual(select === 'multiple' ? 0 :
|
|
1122
|
+
expect(inputEl!.selectionEnd).toEqual(select === 'multiple' ? 0 : 4);
|
|
1111
1123
|
});
|
|
1112
1124
|
|
|
1113
1125
|
testMultiSelect(
|
|
@@ -1288,15 +1300,60 @@ describe('packages/combobox', () => {
|
|
|
1288
1300
|
/**
|
|
1289
1301
|
* onClear
|
|
1290
1302
|
*/
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1303
|
+
describe('onClear', () => {
|
|
1304
|
+
test('Clear button calls onClear callback', () => {
|
|
1305
|
+
const initialValue = select === 'multiple' ? ['apple'] : 'apple';
|
|
1306
|
+
const onClear = jest.fn();
|
|
1307
|
+
const { clearButtonEl } = renderCombobox(select, {
|
|
1308
|
+
initialValue,
|
|
1309
|
+
onClear,
|
|
1310
|
+
});
|
|
1311
|
+
userEvent.click(clearButtonEl!);
|
|
1312
|
+
expect(onClear).toHaveBeenCalled();
|
|
1313
|
+
});
|
|
1314
|
+
|
|
1315
|
+
test('Clear button does not force the menu to reopen', () => {
|
|
1316
|
+
const initialValue = select === 'multiple' ? ['apple'] : 'apple';
|
|
1317
|
+
const onClear = jest.fn();
|
|
1318
|
+
const { clearButtonEl, queryByRole } = renderCombobox(select, {
|
|
1319
|
+
initialValue,
|
|
1320
|
+
onClear,
|
|
1321
|
+
});
|
|
1322
|
+
expect(queryByRole('listbox')).not.toBeInTheDocument();
|
|
1323
|
+
userEvent.click(clearButtonEl!);
|
|
1324
|
+
expect(queryByRole('listbox')).not.toBeInTheDocument();
|
|
1325
|
+
});
|
|
1326
|
+
|
|
1327
|
+
test('Clear button clears the value of the input', () => {
|
|
1328
|
+
const initialValue = select === 'multiple' ? ['apple'] : 'apple';
|
|
1329
|
+
const { inputEl, clearButtonEl, queryChipsByName } = renderCombobox(
|
|
1330
|
+
select,
|
|
1331
|
+
{
|
|
1332
|
+
initialValue,
|
|
1333
|
+
},
|
|
1334
|
+
);
|
|
1335
|
+
|
|
1336
|
+
if (select === 'multiple') {
|
|
1337
|
+
expect(queryChipsByName('Apple')).toBeInTheDocument();
|
|
1338
|
+
} else {
|
|
1339
|
+
expect(inputEl).toHaveValue('Apple');
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
userEvent.click(clearButtonEl!);
|
|
1343
|
+
expect(inputEl).toHaveValue('');
|
|
1344
|
+
});
|
|
1345
|
+
|
|
1346
|
+
test('Focus returns to input element after clear button is clicked', async () => {
|
|
1347
|
+
const initialValue = select === 'multiple' ? ['apple'] : 'apple';
|
|
1348
|
+
const { inputEl, clearButtonEl } = renderCombobox(select, {
|
|
1349
|
+
initialValue,
|
|
1350
|
+
});
|
|
1351
|
+
userEvent.click(clearButtonEl!);
|
|
1352
|
+
|
|
1353
|
+
await waitFor(() => {
|
|
1354
|
+
expect(inputEl).toHaveFocus();
|
|
1355
|
+
});
|
|
1356
|
+
});
|
|
1300
1357
|
});
|
|
1301
1358
|
|
|
1302
1359
|
/**
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { ComponentStory } from '@storybook/react';
|
|
3
3
|
|
|
4
4
|
import Button from '@leafygreen-ui/button';
|
|
5
5
|
import { css } from '@leafygreen-ui/emotion';
|
|
6
6
|
import Icon from '@leafygreen-ui/icon';
|
|
7
|
-
import {
|
|
7
|
+
import { StoryMeta } from '@leafygreen-ui/lib';
|
|
8
8
|
|
|
9
9
|
import {
|
|
10
10
|
ComboboxSize,
|
|
@@ -12,32 +12,21 @@ import {
|
|
|
12
12
|
SearchState,
|
|
13
13
|
State,
|
|
14
14
|
TruncationLocation,
|
|
15
|
-
} from '
|
|
16
|
-
import { Combobox, ComboboxGroup, ComboboxOption } from '
|
|
15
|
+
} from '../Combobox.types';
|
|
16
|
+
import { Combobox, ComboboxGroup, ComboboxOption } from '..';
|
|
17
17
|
|
|
18
18
|
const wrapperStyle = css`
|
|
19
19
|
width: 256px;
|
|
20
20
|
padding-block: 64px;
|
|
21
21
|
`;
|
|
22
22
|
|
|
23
|
-
export default {
|
|
23
|
+
export default StoryMeta({
|
|
24
24
|
title: 'Components/Combobox',
|
|
25
25
|
component: Combobox,
|
|
26
26
|
parameters: {
|
|
27
27
|
default: 'Demo',
|
|
28
28
|
controls: {
|
|
29
|
-
exclude: [
|
|
30
|
-
...storybookExcludedControlParams,
|
|
31
|
-
'onChange',
|
|
32
|
-
'onClear',
|
|
33
|
-
'onFilter',
|
|
34
|
-
'children',
|
|
35
|
-
'aria-label',
|
|
36
|
-
'setError',
|
|
37
|
-
'filteredOptions',
|
|
38
|
-
'initialValue',
|
|
39
|
-
'value',
|
|
40
|
-
],
|
|
29
|
+
exclude: ['as', 'filteredOptions', 'initialValue', 'setError', 'value'],
|
|
41
30
|
},
|
|
42
31
|
},
|
|
43
32
|
argTypes: {
|
|
@@ -110,7 +99,7 @@ export default {
|
|
|
110
99
|
disabled: false,
|
|
111
100
|
clearable: true,
|
|
112
101
|
},
|
|
113
|
-
}
|
|
102
|
+
});
|
|
114
103
|
|
|
115
104
|
const ComboboxOptions = [
|
|
116
105
|
<ComboboxOption key="apple" value="apple" displayName="Apple" />,
|
|
@@ -10,7 +10,11 @@ import {
|
|
|
10
10
|
typeScales,
|
|
11
11
|
} from '@leafygreen-ui/tokens';
|
|
12
12
|
|
|
13
|
-
import {
|
|
13
|
+
import { chipHeight } from '../Chip/Chip.styles';
|
|
14
|
+
import { ComboboxSize as Size, Overflow } from '../Combobox.types';
|
|
15
|
+
|
|
16
|
+
// Rename the variable defined in chip styles
|
|
17
|
+
const inputHeight = chipHeight;
|
|
14
18
|
|
|
15
19
|
/**
|
|
16
20
|
* Width of the widest character (in px)
|
|
@@ -20,24 +24,6 @@ export const maxCharWidth: Record<Size, number> = {
|
|
|
20
24
|
[Size.Large]: typeScales.body2.fontSize,
|
|
21
25
|
};
|
|
22
26
|
|
|
23
|
-
/**
|
|
24
|
-
* Vertical padding on a chip (in px)
|
|
25
|
-
*/
|
|
26
|
-
export const chipWrapperPaddingY = {
|
|
27
|
-
[Size.Default]: 2,
|
|
28
|
-
[Size.Large]: 4,
|
|
29
|
-
} as const;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Height of the input element (in px)
|
|
33
|
-
*/
|
|
34
|
-
export const inputHeight: Record<Size, number> = {
|
|
35
|
-
[Size.Default]:
|
|
36
|
-
typeScales.body1.lineHeight + 2 * chipWrapperPaddingY[Size.Default], // 20
|
|
37
|
-
[Size.Large]:
|
|
38
|
-
typeScales.body2.lineHeight + 2 * chipWrapperPaddingY[Size.Large], // 28
|
|
39
|
-
};
|
|
40
|
-
|
|
41
27
|
/**
|
|
42
28
|
* Size of combobox x & y padding (in px)
|
|
43
29
|
*/
|