@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.
Files changed (82) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/{Chip.d.ts → Chip/Chip.d.ts} +1 -1
  3. package/dist/Chip/Chip.d.ts.map +1 -0
  4. package/dist/Chip/Chip.styles.d.ts +23 -0
  5. package/dist/Chip/Chip.styles.d.ts.map +1 -0
  6. package/dist/Chip/index.d.ts +2 -0
  7. package/dist/Chip/index.d.ts.map +1 -0
  8. package/dist/{Combobox.d.ts → Combobox/Combobox.d.ts} +1 -1
  9. package/dist/Combobox/Combobox.d.ts.map +1 -0
  10. package/dist/{Combobox.styles.d.ts → Combobox/Combobox.styles.d.ts} +1 -12
  11. package/dist/Combobox/Combobox.styles.d.ts.map +1 -0
  12. package/dist/Combobox/index.d.ts +2 -0
  13. package/dist/Combobox/index.d.ts.map +1 -0
  14. package/dist/Combobox.types.d.ts +3 -3
  15. package/dist/Combobox.types.d.ts.map +1 -1
  16. package/dist/{ComboboxContext.d.ts → ComboboxContext/ComboboxContext.d.ts} +1 -4
  17. package/dist/ComboboxContext/ComboboxContext.d.ts.map +1 -0
  18. package/dist/ComboboxContext/index.d.ts +2 -0
  19. package/dist/ComboboxContext/index.d.ts.map +1 -0
  20. package/dist/{ComboboxGroup.d.ts → ComboboxGroup/ComboboxGroup.d.ts} +3 -4
  21. package/dist/ComboboxGroup/ComboboxGroup.d.ts.map +1 -0
  22. package/dist/ComboboxGroup/ComboboxGroup.styles.d.ts +5 -0
  23. package/dist/ComboboxGroup/ComboboxGroup.styles.d.ts.map +1 -0
  24. package/dist/ComboboxGroup/index.d.ts +2 -0
  25. package/dist/ComboboxGroup/index.d.ts.map +1 -0
  26. package/dist/ComboboxMenu/ComboboxMenu.d.ts.map +1 -1
  27. package/dist/ComboboxMenu/index.d.ts +2 -0
  28. package/dist/ComboboxMenu/index.d.ts.map +1 -0
  29. package/dist/{ComboboxOption.d.ts → ComboboxOption/ComboboxOption.d.ts} +5 -4
  30. package/dist/ComboboxOption/ComboboxOption.d.ts.map +1 -0
  31. package/dist/ComboboxOption/ComboboxOption.styles.d.ts +11 -0
  32. package/dist/ComboboxOption/ComboboxOption.styles.d.ts.map +1 -0
  33. package/dist/ComboboxOption/OptionContent.d.ts +4 -0
  34. package/dist/ComboboxOption/OptionContent.d.ts.map +1 -0
  35. package/dist/ComboboxOption/index.d.ts +2 -0
  36. package/dist/ComboboxOption/index.d.ts.map +1 -0
  37. package/dist/esm/index.js +1 -1
  38. package/dist/esm/index.js.map +1 -1
  39. package/dist/index.d.ts +1 -1
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +1 -1
  42. package/dist/index.js.map +1 -1
  43. package/dist/{ComboboxTestUtils.d.ts → utils/ComboboxTestUtils.d.ts} +1 -1
  44. package/dist/utils/ComboboxTestUtils.d.ts.map +1 -0
  45. package/package.json +9 -8
  46. package/src/Chip/Chip.styles.ts +150 -0
  47. package/src/{Chip.tsx → Chip/Chip.tsx} +18 -138
  48. package/src/Chip/index.ts +1 -0
  49. package/src/{Combobox.spec.tsx → Combobox/Combobox.spec.tsx} +72 -15
  50. package/src/{Combobox.story.tsx → Combobox/Combobox.story.tsx} +7 -18
  51. package/src/{Combobox.styles.ts → Combobox/Combobox.styles.ts} +5 -19
  52. package/src/{Combobox.tsx → Combobox/Combobox.tsx} +196 -260
  53. package/src/Combobox/index.ts +1 -0
  54. package/src/Combobox.types.ts +4 -3
  55. package/src/{ComboboxContext.tsx → ComboboxContext/ComboboxContext.tsx} +1 -7
  56. package/src/ComboboxContext/index.ts +1 -0
  57. package/src/ComboboxGroup/ComboboxGroup.styles.ts +34 -0
  58. package/src/ComboboxGroup/ComboboxGroup.tsx +53 -0
  59. package/src/ComboboxGroup/index.ts +1 -0
  60. package/src/ComboboxMenu/ComboboxMenu.tsx +3 -2
  61. package/src/ComboboxMenu/index.ts +1 -0
  62. package/src/ComboboxOption/ComboboxOption.styles.ts +68 -0
  63. package/src/ComboboxOption/ComboboxOption.tsx +107 -0
  64. package/src/ComboboxOption/OptionContent.tsx +87 -0
  65. package/src/ComboboxOption/index.ts +1 -0
  66. package/src/index.ts +1 -1
  67. package/src/{ComboboxTestUtils.tsx → utils/ComboboxTestUtils.tsx} +3 -2
  68. package/tsconfig.json +3 -0
  69. package/tsconfig.tsbuildinfo +1 -1
  70. package/tsdoc.json +543 -3
  71. package/dist/Chip.d.ts.map +0 -1
  72. package/dist/Combobox.d.ts.map +0 -1
  73. package/dist/Combobox.styles.d.ts.map +0 -1
  74. package/dist/ComboboxContext.d.ts.map +0 -1
  75. package/dist/ComboboxGroup.d.ts.map +0 -1
  76. package/dist/ComboboxOption.d.ts.map +0 -1
  77. package/dist/ComboboxTestUtils.d.ts.map +0 -1
  78. package/dist/Menu.styles.d.ts +0 -22
  79. package/dist/Menu.styles.d.ts.map +0 -1
  80. package/src/ComboboxGroup.tsx +0 -80
  81. package/src/ComboboxOption.tsx +0 -327
  82. package/src/Menu.styles.ts +0 -112
@@ -1,80 +0,0 @@
1
- import React, { useContext } from 'react';
2
- import PropTypes from 'prop-types';
3
-
4
- import { css, cx } from '@leafygreen-ui/emotion';
5
- import { useIdAllocator } from '@leafygreen-ui/hooks';
6
- import { Theme } from '@leafygreen-ui/lib';
7
- import { palette } from '@leafygreen-ui/palette';
8
-
9
- import { ComboboxGroupProps } from './Combobox.types';
10
- import { ComboboxContext } from './ComboboxContext';
11
-
12
- const comboboxGroupStyle: Record<Theme, string> = {
13
- [Theme.Light]: css`
14
- padding-top: 8px;
15
- `,
16
- [Theme.Dark]: css`
17
- padding-top: 8px;
18
- `,
19
- };
20
-
21
- const comboboxGroupLabel = css`
22
- cursor: default;
23
- width: 100%;
24
- padding: 0 12px 2px;
25
- outline: none;
26
- overflow-wrap: anywhere;
27
- font-size: 12px;
28
- line-height: 16px;
29
- font-weight: bold;
30
- text-transform: uppercase;
31
- letter-spacing: 0.4px;
32
- `;
33
-
34
- const comboboxGroupLabelThemeStyle: Record<Theme, string> = {
35
- [Theme.Light]: css`
36
- color: ${palette.gray.dark1};
37
- `,
38
- [Theme.Dark]: css`
39
- color: ${palette.gray.light1};
40
- `,
41
- };
42
-
43
- export function InternalComboboxGroup({
44
- label,
45
- className,
46
- children,
47
- }: ComboboxGroupProps): JSX.Element {
48
- const { theme } = useContext(ComboboxContext);
49
-
50
- const groupId = useIdAllocator({ prefix: 'combobox-group' });
51
- const childCount = React.Children.count(children);
52
-
53
- return childCount > 0 ? (
54
- <div className={cx(comboboxGroupStyle[theme], className)}>
55
- <div
56
- className={cx(comboboxGroupLabel, comboboxGroupLabelThemeStyle[theme])}
57
- id={groupId}
58
- >
59
- {label}
60
- </div>
61
- <div role="group" aria-labelledby={groupId}>
62
- {children}
63
- </div>
64
- </div>
65
- ) : (
66
- <></>
67
- );
68
- }
69
-
70
- ComboboxGroup.displayName = 'ComboboxGroup';
71
-
72
- ComboboxGroup.propTypes = {
73
- className: PropTypes.string,
74
- children: PropTypes.node.isRequired,
75
- label: PropTypes.string.isRequired,
76
- };
77
-
78
- export default function ComboboxGroup(_: ComboboxGroupProps): JSX.Element {
79
- throw Error('`ComboboxGroup` must be a child of a `Combobox` instance');
80
- }
@@ -1,327 +0,0 @@
1
- import React, { useCallback, useContext, useMemo } from 'react';
2
- import PropTypes from 'prop-types';
3
-
4
- import Checkbox from '@leafygreen-ui/checkbox';
5
- import { css, cx } from '@leafygreen-ui/emotion';
6
- import { useForwardedRef, useIdAllocator } from '@leafygreen-ui/hooks';
7
- import Icon, { isComponentGlyph } from '@leafygreen-ui/icon';
8
- import { Theme } from '@leafygreen-ui/lib';
9
- import { palette } from '@leafygreen-ui/palette';
10
- import { fontFamilies, spacing, typeScales } from '@leafygreen-ui/tokens';
11
-
12
- import { menuItemHeight, menuItemPadding } from './ComboboxMenu/Menu.styles';
13
- import {
14
- ComboboxOptionProps,
15
- ComboboxSize as Size,
16
- InternalComboboxOptionProps,
17
- } from './Combobox.types';
18
- import { ComboboxContext } from './ComboboxContext';
19
- import { wrapJSX } from './utils';
20
-
21
- /**
22
- * Styles
23
- */
24
-
25
- const comboboxOptionBaseStyle = css`
26
- position: relative;
27
- display: flex;
28
- align-items: center;
29
- justify-content: space-between;
30
- list-style: none;
31
- color: inherit;
32
- cursor: pointer;
33
- overflow: hidden;
34
- font-family: ${fontFamilies.default};
35
-
36
- // Left wedge
37
- &:before {
38
- content: '';
39
- position: absolute;
40
- left: 0;
41
- width: 4px;
42
- height: calc(100% - 14px);
43
- background-color: rgba(255, 255, 255, 0);
44
- border-radius: 0 6px 6px 0;
45
- transform: scale3d(0, 0.3, 0);
46
- transition: 200ms ease-in-out;
47
- transition-property: transform, background-color;
48
- }
49
- `;
50
-
51
- const comboboxOptionThemeStyle: Record<Theme, string> = {
52
- [Theme.Light]: css`
53
- &:hover {
54
- outline: none;
55
- background-color: ${palette.gray.light2};
56
- }
57
- `,
58
- [Theme.Dark]: css`
59
- &:hover {
60
- outline: none;
61
- background-color: ${palette.gray.dark4};
62
- }
63
- `,
64
- };
65
-
66
- const comboboxOptionSizeStyle: Record<Size, string> = {
67
- [Size.Default]: css`
68
- font-size: ${typeScales.body1.fontSize}px;
69
- line-height: ${typeScales.body1.lineHeight}px;
70
- min-height: ${menuItemHeight[Size.Default]}px;
71
- padding: ${menuItemPadding[Size.Default].y}px
72
- ${menuItemPadding[Size.Default].x}px;
73
- gap: ${spacing[1]}px;
74
-
75
- &:before {
76
- max-height: ${menuItemHeight[Size.Default]}px;
77
- }
78
- `,
79
- [Size.Large]: css`
80
- font-size: ${typeScales.body2.fontSize}px;
81
- line-height: ${typeScales.body2.lineHeight}px;
82
- min-height: ${menuItemHeight[Size.Large]}px;
83
- padding: ${menuItemPadding[Size.Large].y}px
84
- ${menuItemPadding[Size.Large].x}px;
85
- gap: ${spacing[2]}px;
86
-
87
- &:before {
88
- max-height: ${menuItemHeight[Size.Large]}px;
89
- }
90
- `,
91
- };
92
-
93
- const _comboboxOptionBaseActiveStyle = css`
94
- outline: none;
95
-
96
- &:before {
97
- transform: scaleY(1);
98
- }
99
- `;
100
-
101
- const comboboxOptionActiveStyle: Record<Theme, string> = {
102
- [Theme.Light]: css`
103
- ${_comboboxOptionBaseActiveStyle};
104
- background-color: ${palette.blue.light3};
105
-
106
- &:before {
107
- background-color: ${palette.blue.base};
108
- }
109
- `,
110
- [Theme.Dark]: css`
111
- ${_comboboxOptionBaseActiveStyle};
112
- background-color: ${palette.blue.dark3};
113
-
114
- &:before {
115
- background-color: ${palette.blue.light1};
116
- }
117
- `,
118
- };
119
-
120
- const _comboboxOptionBaseDisabledStyle = css`
121
- cursor: not-allowed;
122
-
123
- &:hover {
124
- background-color: inherit;
125
- }
126
-
127
- &:before {
128
- content: unset;
129
- }
130
- `;
131
-
132
- const comboboxOptionDisabledStyle: Record<Theme, string> = {
133
- [Theme.Light]: css`
134
- ${_comboboxOptionBaseDisabledStyle};
135
- color: ${palette.gray.light1};
136
- `,
137
- [Theme.Dark]: css`
138
- ${_comboboxOptionBaseDisabledStyle};
139
- color: ${palette.gray.dark1};
140
- `,
141
- };
142
-
143
- const checkIconStyle: Record<Size, string> = {
144
- [Size.Default]: css`
145
- min-width: ${spacing[3]}px;
146
- `,
147
- [Size.Large]: css`
148
- min-width: ${spacing[4]}px;
149
- `,
150
- };
151
-
152
- const flexSpan = css`
153
- display: inline-flex;
154
- gap: 8px;
155
- justify-content: start;
156
- align-items: inherit;
157
- overflow-wrap: anywhere;
158
- `;
159
-
160
- const disallowPointer = css`
161
- pointer-events: none;
162
- `;
163
-
164
- const displayNameStyle = (isSelected: boolean) => css`
165
- font-weight: ${isSelected ? 'bold' : 'normal'};
166
- `;
167
-
168
- /**
169
- * Component
170
- */
171
- const InternalComboboxOption = React.forwardRef<
172
- HTMLLIElement,
173
- InternalComboboxOptionProps
174
- >(
175
- (
176
- {
177
- displayName,
178
- glyph,
179
- isSelected,
180
- isFocused,
181
- disabled,
182
- setSelected,
183
- className,
184
- }: InternalComboboxOptionProps,
185
- forwardedRef,
186
- ) => {
187
- const { multiselect, darkMode, theme, withIcons, inputValue, size } =
188
- useContext(ComboboxContext);
189
- const optionTextId = useIdAllocator({ prefix: 'combobox-option-text' });
190
- const optionRef = useForwardedRef(forwardedRef, null);
191
-
192
- const handleOptionClick = useCallback(
193
- (e: React.SyntheticEvent) => {
194
- // stopPropagation will not stop the keyDown event (only click)
195
- // since the option is never `focused`, only `aria-selected`
196
- // the keyDown event does not actually fire on the option element
197
- e.stopPropagation();
198
-
199
- // If user clicked on the option, or the checkbox
200
- // Ignore extra click events on the checkbox wrapper
201
- if (
202
- !disabled &&
203
- (e.target === optionRef.current ||
204
- (e.target as Element).tagName === 'INPUT')
205
- ) {
206
- setSelected();
207
- }
208
- },
209
- [disabled, optionRef, setSelected],
210
- );
211
-
212
- const renderedIcon = useMemo(() => {
213
- if (glyph) {
214
- if (isComponentGlyph(glyph)) {
215
- return glyph;
216
- }
217
- console.error(
218
- '`ComboboxOption` instance did not render icon because it is not a known glyph element.',
219
- glyph,
220
- );
221
- }
222
- }, [glyph]);
223
-
224
- const renderedChildren = useMemo(() => {
225
- // Multiselect
226
- if (multiselect) {
227
- const checkbox = (
228
- <Checkbox
229
- aria-labelledby={optionTextId}
230
- checked={isSelected}
231
- tabIndex={-1}
232
- disabled={disabled}
233
- darkMode={darkMode}
234
- className={css`
235
- // TODO: Remove when this is resolved:
236
- // https://jira.mongodb.org/browse/PD-2171
237
- & > label > div {
238
- margin-top: 0;
239
- }
240
- `}
241
- />
242
- );
243
-
244
- return (
245
- <>
246
- <span className={cx(flexSpan, disallowPointer)}>
247
- {withIcons ? renderedIcon : checkbox}
248
- <span id={optionTextId} className={displayNameStyle(isSelected)}>
249
- {wrapJSX(displayName, inputValue, 'strong')}
250
- </span>
251
- </span>
252
- {withIcons && checkbox}
253
- </>
254
- );
255
- }
256
-
257
- // Single select
258
- return (
259
- <>
260
- <span className={cx(flexSpan, disallowPointer)}>
261
- {renderedIcon}
262
- <span className={displayNameStyle(isSelected)}>
263
- {wrapJSX(displayName, inputValue, 'strong')}
264
- </span>
265
- </span>
266
- {isSelected && (
267
- <Icon
268
- glyph="Checkmark"
269
- className={checkIconStyle[size]}
270
- color={darkMode ? palette.blue.light1 : palette.blue.base}
271
- />
272
- )}
273
- </>
274
- );
275
- }, [
276
- multiselect,
277
- renderedIcon,
278
- isSelected,
279
- displayName,
280
- inputValue,
281
- size,
282
- darkMode,
283
- optionTextId,
284
- disabled,
285
- withIcons,
286
- ]);
287
-
288
- return (
289
- <li
290
- ref={optionRef}
291
- role="option"
292
- aria-selected={isFocused}
293
- aria-label={displayName}
294
- tabIndex={-1}
295
- className={cx(
296
- comboboxOptionBaseStyle,
297
- comboboxOptionSizeStyle[size],
298
- comboboxOptionThemeStyle[theme],
299
- {
300
- [comboboxOptionActiveStyle[theme]]: isFocused,
301
- [comboboxOptionDisabledStyle[theme]]: disabled,
302
- },
303
- className,
304
- )}
305
- onClick={handleOptionClick}
306
- onKeyDown={handleOptionClick}
307
- >
308
- {renderedChildren}
309
- </li>
310
- );
311
- },
312
- );
313
- InternalComboboxOption.displayName = 'ComboboxOption';
314
-
315
- export { InternalComboboxOption };
316
- export function ComboboxOption(_: ComboboxOptionProps): JSX.Element {
317
- throw Error('`ComboboxOption` must be a child of a `Combobox` instance');
318
- }
319
- ComboboxOption.displayName = 'ComboboxOption';
320
-
321
- ComboboxOption.propTypes = {
322
- displayName: PropTypes.string,
323
- value: PropTypes.string,
324
- glyph: PropTypes.node,
325
- disabled: PropTypes.bool,
326
- className: PropTypes.string,
327
- };
@@ -1,112 +0,0 @@
1
- import { css, keyframes } from '@leafygreen-ui/emotion';
2
- import { Theme } from '@leafygreen-ui/lib';
3
- import { palette } from '@leafygreen-ui/palette';
4
- import { fontFamilies, typeScales } from '@leafygreen-ui/tokens';
5
-
6
- import { ComboboxSize } from './Combobox.types';
7
-
8
- /** Height of a menu item (in px) */
9
- export const menuItemHeight = 36;
10
-
11
- export const menuItemPadding: Record<ComboboxSize, { x: number; y: number }> = {
12
- [ComboboxSize.Default]: { x: 12, y: 8 },
13
- [ComboboxSize.Large]: { x: 12, y: 8 },
14
- };
15
-
16
- /**
17
- * Menu styles
18
- */
19
-
20
- export const popoverStyle = (width = 384) => css`
21
- border-radius: 4px;
22
- width: ${width}px;
23
- overflow: hidden;
24
- `;
25
-
26
- export const popoverThemeStyle: Record<Theme, string> = {
27
- [Theme.Light]: css`
28
- box-shadow: 0px 3px 7px rgba(0, 0, 0, 0.25);
29
- `,
30
- [Theme.Dark]: css``, // TODO: DarkMode
31
- };
32
-
33
- export const menuBaseStyle = css`
34
- position: relative;
35
- width: 100%;
36
- margin: 0;
37
- padding: 0;
38
- font-family: ${fontFamilies.default};
39
- border-radius: inherit;
40
- overflow-y: auto;
41
- scroll-behavior: smooth;
42
- min-height: ${menuItemHeight}px;
43
- `;
44
-
45
- export const menuThemeStyle: Record<Theme, string> = {
46
- [Theme.Light]: css`
47
- color: ${palette.gray.dark3};
48
- background-color: ${palette.white};
49
- `,
50
- [Theme.Dark]: css``, // TODO: DarkMode
51
- };
52
-
53
- export const menuList = css`
54
- position: relative;
55
- margin: 0;
56
- padding: 0;
57
- `;
58
-
59
- export const menuMessageBaseStyle = css`
60
- font-family: inherit;
61
- display: inline-flex;
62
- align-items: center;
63
- gap: 8px;
64
- `;
65
-
66
- export const menuMessageThemeStyle: Record<Theme, string> = {
67
- [Theme.Light]: css`
68
- ${palette.gray.dark1}
69
- `,
70
- [Theme.Dark]: css``, // TODO: DarkMode
71
- };
72
-
73
- export const menuMessageSizeStyle: Record<ComboboxSize, string> = {
74
- [ComboboxSize.Default]: css`
75
- font-size: ${typeScales.body1.fontSize +
76
- 1}px; // TODO: update this @ redesign
77
- line-height: ${typeScales.body1.lineHeight +
78
- 1}px; // TODO: update this @ redesign
79
- padding: ${menuItemPadding[ComboboxSize.Default].y}px
80
- ${menuItemPadding[ComboboxSize.Default].x}px;
81
- `,
82
- [ComboboxSize.Large]: css`
83
- font-size: ${typeScales.body2.fontSize}px;
84
- line-height: ${typeScales.body2.lineHeight}px;
85
- padding: ${menuItemPadding[ComboboxSize.Large].y}px
86
- ${menuItemPadding[ComboboxSize.Large].x}px;
87
- `,
88
- };
89
-
90
- export const menuMessageIconSizeStyle: Record<ComboboxSize, string> = {
91
- [ComboboxSize.Default]: css`
92
- height: ${typeScales.body1.fontSize + 1}px; // TODO: update this @ redesign
93
- width: ${typeScales.body1.fontSize + 1}px; // TODO: update this @ redesign
94
- `,
95
- [ComboboxSize.Large]: css`
96
- height: ${typeScales.body2.fontSize}px;
97
- width: ${typeScales.body2.fontSize}px;
98
- `,
99
- };
100
-
101
- const loadingIconAnimation = keyframes`
102
- 0% {
103
- transform: rotate(0deg);
104
- }
105
- 100% {
106
- transform: rotate(360deg);
107
- }
108
- `;
109
-
110
- export const loadingIconStyle = css`
111
- animation: ${loadingIconAnimation} 1.5s linear infinite;
112
- `;