@workday/canvas-kit-labs-react 15.0.0-alpha.0060-next.0 → 15.0.0-alpha.0074-next.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/dist/commonjs/ai-ingress-button/lib/AIIngressButton.js +5 -5
- package/dist/commonjs/index.d.ts +0 -2
- package/dist/commonjs/index.d.ts.map +1 -1
- package/dist/commonjs/index.js +0 -2
- package/dist/commonjs/side-panel/lib/SidePanel.js +7 -7
- package/dist/commonjs/side-panel/lib/SidePanelToggleButton.js +11 -11
- package/dist/commonjs/version/lib/version.js +1 -1
- package/dist/es6/ai-ingress-button/lib/AIIngressButton.js +5 -5
- package/dist/es6/index.d.ts +0 -2
- package/dist/es6/index.d.ts.map +1 -1
- package/dist/es6/index.js +0 -2
- package/dist/es6/side-panel/lib/SidePanel.js +7 -7
- package/dist/es6/side-panel/lib/SidePanelToggleButton.js +11 -11
- package/dist/es6/version/lib/version.js +1 -1
- package/index.ts +0 -2
- package/package.json +4 -4
- package/combobox/index.ts +0 -1
- package/combobox/lib/AutocompleteList.tsx +0 -137
- package/combobox/lib/Combobox.tsx +0 -505
- package/combobox/lib/Status.tsx +0 -52
- package/combobox/package.json +0 -6
- package/dist/commonjs/combobox/index.d.ts +0 -2
- package/dist/commonjs/combobox/index.d.ts.map +0 -1
- package/dist/commonjs/combobox/index.js +0 -17
- package/dist/commonjs/combobox/lib/AutocompleteList.d.ts +0 -34
- package/dist/commonjs/combobox/lib/AutocompleteList.d.ts.map +0 -1
- package/dist/commonjs/combobox/lib/AutocompleteList.js +0 -101
- package/dist/commonjs/combobox/lib/Combobox.d.ts +0 -79
- package/dist/commonjs/combobox/lib/Combobox.d.ts.map +0 -1
- package/dist/commonjs/combobox/lib/Combobox.js +0 -349
- package/dist/commonjs/combobox/lib/Status.d.ts +0 -16
- package/dist/commonjs/combobox/lib/Status.d.ts.map +0 -1
- package/dist/commonjs/combobox/lib/Status.js +0 -29
- package/dist/commonjs/search-form/index.d.ts +0 -3
- package/dist/commonjs/search-form/index.d.ts.map +0 -1
- package/dist/commonjs/search-form/index.js +0 -18
- package/dist/commonjs/search-form/lib/SearchForm.d.ts +0 -450
- package/dist/commonjs/search-form/lib/SearchForm.d.ts.map +0 -1
- package/dist/commonjs/search-form/lib/SearchForm.js +0 -236
- package/dist/commonjs/search-form/lib/themes.d.ts +0 -33
- package/dist/commonjs/search-form/lib/themes.d.ts.map +0 -1
- package/dist/commonjs/search-form/lib/themes.js +0 -47
- package/dist/es6/combobox/index.d.ts +0 -2
- package/dist/es6/combobox/index.d.ts.map +0 -1
- package/dist/es6/combobox/index.js +0 -1
- package/dist/es6/combobox/lib/AutocompleteList.d.ts +0 -34
- package/dist/es6/combobox/lib/AutocompleteList.d.ts.map +0 -1
- package/dist/es6/combobox/lib/AutocompleteList.js +0 -71
- package/dist/es6/combobox/lib/Combobox.d.ts +0 -79
- package/dist/es6/combobox/lib/Combobox.d.ts.map +0 -1
- package/dist/es6/combobox/lib/Combobox.js +0 -317
- package/dist/es6/combobox/lib/Status.d.ts +0 -16
- package/dist/es6/combobox/lib/Status.d.ts.map +0 -1
- package/dist/es6/combobox/lib/Status.js +0 -22
- package/dist/es6/search-form/index.d.ts +0 -3
- package/dist/es6/search-form/index.d.ts.map +0 -1
- package/dist/es6/search-form/index.js +0 -2
- package/dist/es6/search-form/lib/SearchForm.d.ts +0 -450
- package/dist/es6/search-form/lib/SearchForm.d.ts.map +0 -1
- package/dist/es6/search-form/lib/SearchForm.js +0 -207
- package/dist/es6/search-form/lib/themes.d.ts +0 -33
- package/dist/es6/search-form/lib/themes.d.ts.map +0 -1
- package/dist/es6/search-form/lib/themes.js +0 -44
- package/search-form/index.ts +0 -2
- package/search-form/lib/SearchForm.tsx +0 -651
- package/search-form/lib/themes.ts +0 -67
- package/search-form/package.json +0 -6
|
@@ -1,505 +0,0 @@
|
|
|
1
|
-
import React, {useEffect, useLayoutEffect, useRef, useState, useCallback} from 'react';
|
|
2
|
-
import {jsx, keyframes, CSSObject} from '@emotion/react';
|
|
3
|
-
import {
|
|
4
|
-
GrowthBehavior,
|
|
5
|
-
useForkRef,
|
|
6
|
-
styled,
|
|
7
|
-
useUniqueId,
|
|
8
|
-
filterOutProps,
|
|
9
|
-
} from '@workday/canvas-kit-react/common';
|
|
10
|
-
import {space, commonColors, borderRadius} from '@workday/canvas-kit-react/tokens';
|
|
11
|
-
import {Card} from '@workday/canvas-kit-react/card';
|
|
12
|
-
import {TertiaryButton, TertiaryButtonProps} from '@workday/canvas-kit-react/button';
|
|
13
|
-
import {xSmallIcon} from '@workday/canvas-system-icons-web';
|
|
14
|
-
import {TextInputProps} from '@workday/canvas-kit-react/text-input';
|
|
15
|
-
import flatten from 'lodash.flatten';
|
|
16
|
-
import {AutocompleteList} from './AutocompleteList';
|
|
17
|
-
import {Status} from './Status';
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @deprecated ⚠️ `ComboBoxMenuItemGroup` in Labs has been deprecated and will be removed in a future major version. Please use [`Combobox` in Main](https://workday.github.io/canvas-kit/?path=/docs/features-combobox--docs) instead.
|
|
21
|
-
*/
|
|
22
|
-
export interface ComboBoxMenuItemGroup {
|
|
23
|
-
// A non intractable header that logically separates autocomplete items
|
|
24
|
-
header: React.ReactElement<any>;
|
|
25
|
-
// A group of logically distinct autocomplete items
|
|
26
|
-
items: React.ReactElement<any>[];
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* @deprecated ⚠️ `ComboboxProps` in Labs has been deprecated and will be removed in a future major version. Please use [`Combobox` in Main](https://workday.github.io/canvas-kit/?path=/docs/features-combobox--docs) instead.
|
|
31
|
-
*/
|
|
32
|
-
export interface ComboboxProps extends GrowthBehavior, React.HTMLAttributes<HTMLElement> {
|
|
33
|
-
/**
|
|
34
|
-
* The TextInput child of the Combobox.
|
|
35
|
-
*/
|
|
36
|
-
children: React.ReactElement<TextInputProps>;
|
|
37
|
-
/**
|
|
38
|
-
* The initial value of the Combobox.
|
|
39
|
-
*/
|
|
40
|
-
initialValue?: string;
|
|
41
|
-
/**
|
|
42
|
-
* The variant of the Combobox clear button. The default is a TertiaryButton
|
|
43
|
-
*/
|
|
44
|
-
clearButtonVariant?: TertiaryButtonProps['variant'];
|
|
45
|
-
/**
|
|
46
|
-
* If true, render the Combobox with a button to clear the text input.
|
|
47
|
-
* @default false
|
|
48
|
-
*/
|
|
49
|
-
showClearButton?: boolean;
|
|
50
|
-
/**
|
|
51
|
-
* The `aria-label` for the Combobox clear button.
|
|
52
|
-
* @default Reset Search Input
|
|
53
|
-
*/
|
|
54
|
-
clearButtonAriaLabel?: string;
|
|
55
|
-
/**
|
|
56
|
-
* The autocomplete items of the Combobox. This array of menu items is shown under the text input.
|
|
57
|
-
*/
|
|
58
|
-
autocompleteItems?: React.ReactElement<any>[] | ComboBoxMenuItemGroup[];
|
|
59
|
-
/**
|
|
60
|
-
* The function called when the Combobox text input changes.
|
|
61
|
-
*/
|
|
62
|
-
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
63
|
-
/**
|
|
64
|
-
* The function called when the Combobox text input focuses.
|
|
65
|
-
*/
|
|
66
|
-
onFocus?: React.FocusEventHandler;
|
|
67
|
-
/**
|
|
68
|
-
* The function called when the Combobox text input blurs.
|
|
69
|
-
*/
|
|
70
|
-
onBlur?: React.FocusEventHandler;
|
|
71
|
-
/**
|
|
72
|
-
* The id of the form field.
|
|
73
|
-
*/
|
|
74
|
-
labelId?: string;
|
|
75
|
-
/**
|
|
76
|
-
* The text for screen readers announcing the autocomplete count
|
|
77
|
-
*/
|
|
78
|
-
getStatusText?: (listCount: number) => string;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const Container = styled('div')<Pick<ComboboxProps, 'grow'>>(
|
|
82
|
-
{
|
|
83
|
-
display: 'inline-block',
|
|
84
|
-
},
|
|
85
|
-
({grow}) => ({
|
|
86
|
-
width: grow ? '100%' : 'auto',
|
|
87
|
-
})
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
const InputContainer = styled('div')({
|
|
91
|
-
display: `flex`,
|
|
92
|
-
alignItems: `center`,
|
|
93
|
-
position: 'relative',
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
const fadeInKeyframes = keyframes({
|
|
97
|
-
'0%': {
|
|
98
|
-
opacity: 0,
|
|
99
|
-
},
|
|
100
|
-
'100%': {
|
|
101
|
-
opacity: 1,
|
|
102
|
-
},
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
const MenuContainer = styled(Card)({
|
|
106
|
-
position: 'absolute',
|
|
107
|
-
zIndex: 1,
|
|
108
|
-
left: 0,
|
|
109
|
-
top: '100%',
|
|
110
|
-
borderRadius: borderRadius.m,
|
|
111
|
-
background: commonColors.background,
|
|
112
|
-
border: `none`,
|
|
113
|
-
marginTop: `-${borderRadius.m}`,
|
|
114
|
-
width: '100%',
|
|
115
|
-
minWidth: 0,
|
|
116
|
-
animation: `${fadeInKeyframes} 200ms ease-out`,
|
|
117
|
-
maxHeight: 200,
|
|
118
|
-
overflow: 'hidden',
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
const ResetButton = styled(TertiaryButton, {
|
|
122
|
-
shouldForwardProp: filterOutProps(['shouldShow']),
|
|
123
|
-
})<{shouldShow: boolean}>(
|
|
124
|
-
{
|
|
125
|
-
position: 'absolute',
|
|
126
|
-
margin: `auto ${space.xxxs}`,
|
|
127
|
-
top: 0,
|
|
128
|
-
bottom: 0,
|
|
129
|
-
right: 0,
|
|
130
|
-
padding: 0,
|
|
131
|
-
zIndex: 2,
|
|
132
|
-
transition: 'opacity 120ms',
|
|
133
|
-
},
|
|
134
|
-
({shouldShow}) => ({
|
|
135
|
-
visibility: shouldShow ? 'visible' : 'hidden',
|
|
136
|
-
opacity: shouldShow ? 1 : 0,
|
|
137
|
-
})
|
|
138
|
-
);
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* @deprecated ⚠️ `listBoxIdPart` in Labs has been deprecated and will be removed in a future major version. Please use [`Combobox` in Main](https://workday.github.io/canvas-kit/?path=/docs/features-combobox--docs) instead.
|
|
142
|
-
*/
|
|
143
|
-
export const listBoxIdPart = `listbox`;
|
|
144
|
-
const optionIdPart = `option`;
|
|
145
|
-
/**
|
|
146
|
-
* @deprecated ⚠️ `getOptionId` in Labs has been deprecated and will be removed in a future major version. Please use [`Combobox` in Main](https://workday.github.io/canvas-kit/?path=/docs/features-combobox--docs) instead.
|
|
147
|
-
*/
|
|
148
|
-
export const getOptionId = (baseId?: string, index?: number) =>
|
|
149
|
-
`${baseId}-${optionIdPart}-${index}`;
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* @deprecated ⚠️ `getTextFromElement` in Labs has been deprecated and will be removed in a future major version. Please use [`Combobox` in Main](https://workday.github.io/canvas-kit/?path=/docs/features-combobox--docs) instead.
|
|
153
|
-
*/
|
|
154
|
-
export const getTextFromElement = (children?: React.ReactNode) => {
|
|
155
|
-
let text = '';
|
|
156
|
-
React.Children.map(children, child => {
|
|
157
|
-
if (child == null || typeof child === 'boolean') {
|
|
158
|
-
text += '';
|
|
159
|
-
} else if (typeof child === 'string' || typeof child === 'number') {
|
|
160
|
-
text += child.toString();
|
|
161
|
-
} else if (Array.isArray(child)) {
|
|
162
|
-
text += getTextFromElement(child);
|
|
163
|
-
} else if ('props' in child) {
|
|
164
|
-
text += getTextFromElement(child.props.children);
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
return text;
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
const buildStatusString = (listCount: number): string => {
|
|
171
|
-
return `There ${listCount === 1 ? 'is' : 'are'} ${listCount} suggestion${
|
|
172
|
-
listCount === 1 ? '' : 's'
|
|
173
|
-
}.`;
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
const isValidSingleChild = (child: React.ReactNode) => {
|
|
177
|
-
return React.isValidElement(child) && React.Children.only(child);
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* @deprecated ⚠️ `Combobox` in Labs has been deprecated and will be removed in a future major version. Please use [`Combobox` in Main](https://workday.github.io/canvas-kit/?path=/docs/features-combobox--docs) instead.
|
|
182
|
-
*/
|
|
183
|
-
export const Combobox = ({
|
|
184
|
-
autocompleteItems,
|
|
185
|
-
children,
|
|
186
|
-
grow,
|
|
187
|
-
initialValue,
|
|
188
|
-
onChange,
|
|
189
|
-
onFocus,
|
|
190
|
-
onBlur,
|
|
191
|
-
showClearButton,
|
|
192
|
-
clearButtonVariant = undefined,
|
|
193
|
-
clearButtonAriaLabel = `Reset Search Input`,
|
|
194
|
-
labelId,
|
|
195
|
-
getStatusText = buildStatusString,
|
|
196
|
-
id,
|
|
197
|
-
...elemProps
|
|
198
|
-
}: ComboboxProps) => {
|
|
199
|
-
const [isOpened, setIsOpened] = useState(false);
|
|
200
|
-
const [value, _setValue] = useState(''); // Don't call _setValue directly instead call setInputValue to make sure onChange fires correctly
|
|
201
|
-
const [showingAutocomplete, setShowingAutocomplete] = useState(false);
|
|
202
|
-
const [selectedAutocompleteIndex, setSelectedAutocompleteIndex] = useState<number | null>(null);
|
|
203
|
-
const [interactiveAutocompleteItems, setInteractiveAutocompleteItems] = useState<
|
|
204
|
-
React.ReactElement<any>[]
|
|
205
|
-
>([]);
|
|
206
|
-
const [announcementText, setAnnouncementText] = useState('');
|
|
207
|
-
|
|
208
|
-
// Create a ref to the soon-to-be-created TextInput clone for internal use.
|
|
209
|
-
// Use useForkRef to combine it with the ref already assigned to the original
|
|
210
|
-
// TextInput (if it exists) to create a single callback ref which can be
|
|
211
|
-
// forwarded to the TextInput clone.
|
|
212
|
-
const inputRef: React.RefObject<HTMLInputElement> = useRef(null);
|
|
213
|
-
// We need access to the original TextInput's ref _property_ (not prop) so we
|
|
214
|
-
// can combine it with the internal inputRef using useForkRef. ref isn't
|
|
215
|
-
// listed in the ReactElement interface, but it's there, so we cast children
|
|
216
|
-
// to satisfy TS.
|
|
217
|
-
const elementRef = useForkRef(
|
|
218
|
-
(children as React.ReactElement<TextInputProps> & {ref: React.Ref<HTMLInputElement>}).ref,
|
|
219
|
-
inputRef
|
|
220
|
-
);
|
|
221
|
-
|
|
222
|
-
const comboboxRef: React.RefObject<HTMLDivElement> = useRef(null);
|
|
223
|
-
|
|
224
|
-
const randomComponentId = useUniqueId();
|
|
225
|
-
const randomLabelId = useUniqueId();
|
|
226
|
-
|
|
227
|
-
const componentId = id || randomComponentId;
|
|
228
|
-
const formLabelId = labelId || randomLabelId;
|
|
229
|
-
|
|
230
|
-
const [showGroupText, setShowGroupText] = useState(false);
|
|
231
|
-
|
|
232
|
-
// We're using LayoutEffect here because of an issue with the Synthetic event system and typing a key
|
|
233
|
-
// after the listbox has been closed. Somehow the key is ignored unless we use `useLayoutEffect`
|
|
234
|
-
useLayoutEffect(() => {
|
|
235
|
-
const shouldShow = interactiveAutocompleteItems.length > 0 && isOpened;
|
|
236
|
-
setShowingAutocomplete(shouldShow);
|
|
237
|
-
if (shouldShow) {
|
|
238
|
-
setAnnouncementText(getStatusText(interactiveAutocompleteItems.length));
|
|
239
|
-
}
|
|
240
|
-
}, [getStatusText, interactiveAutocompleteItems, isOpened]);
|
|
241
|
-
|
|
242
|
-
const setInputValue = useCallback(
|
|
243
|
-
(newValue: string) => {
|
|
244
|
-
_setValue(newValue);
|
|
245
|
-
const inputDomElement = inputRef.current;
|
|
246
|
-
// Changing value prop programmatically doesn't fire an Synthetic event or trigger native onChange.
|
|
247
|
-
// We can not just update .value= in setState because React library overrides input value setter
|
|
248
|
-
// but we can call the function directly on the input as context.
|
|
249
|
-
// This will cause onChange events to fire no matter how value is updated.
|
|
250
|
-
if (inputDomElement) {
|
|
251
|
-
const nativeInputValue = Object.getOwnPropertyDescriptor(
|
|
252
|
-
Object.getPrototypeOf(inputDomElement),
|
|
253
|
-
'value'
|
|
254
|
-
);
|
|
255
|
-
if (nativeInputValue && nativeInputValue.set) {
|
|
256
|
-
nativeInputValue.set.call(inputDomElement, newValue);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
let event: Event;
|
|
260
|
-
if (typeof Event === 'function') {
|
|
261
|
-
// modern browsers
|
|
262
|
-
event = new Event('input', {bubbles: true});
|
|
263
|
-
} else {
|
|
264
|
-
// IE 11
|
|
265
|
-
event = document.createEvent('Event');
|
|
266
|
-
event.initEvent('input', true, true);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
inputDomElement.dispatchEvent(event);
|
|
270
|
-
}
|
|
271
|
-
},
|
|
272
|
-
[inputRef]
|
|
273
|
-
);
|
|
274
|
-
|
|
275
|
-
useEffect(() => {
|
|
276
|
-
if (initialValue !== null && initialValue !== undefined) {
|
|
277
|
-
setInputValue(initialValue);
|
|
278
|
-
}
|
|
279
|
-
}, [initialValue, setInputValue]);
|
|
280
|
-
|
|
281
|
-
useEffect(() => {
|
|
282
|
-
const getInteractiveAutocompleteItems = (): React.ReactElement<any>[] => {
|
|
283
|
-
if (
|
|
284
|
-
autocompleteItems &&
|
|
285
|
-
autocompleteItems.length &&
|
|
286
|
-
autocompleteItems[0].hasOwnProperty('header')
|
|
287
|
-
) {
|
|
288
|
-
return flatten((autocompleteItems as ComboBoxMenuItemGroup[]).map(group => group.items));
|
|
289
|
-
}
|
|
290
|
-
return (autocompleteItems as React.ReactElement<any>[]) || [];
|
|
291
|
-
};
|
|
292
|
-
setInteractiveAutocompleteItems(getInteractiveAutocompleteItems());
|
|
293
|
-
}, [autocompleteItems]);
|
|
294
|
-
|
|
295
|
-
const handleAutocompleteClick = (
|
|
296
|
-
event: React.SyntheticEvent<Element, Event>,
|
|
297
|
-
menuItemProps: any
|
|
298
|
-
): void => {
|
|
299
|
-
if (menuItemProps.isDisabled || menuItemProps['aria-disabled']) {
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
setShowingAutocomplete(false);
|
|
303
|
-
setIsOpened(false);
|
|
304
|
-
setInputValue(getTextFromElement(menuItemProps.children));
|
|
305
|
-
if (menuItemProps.onClick) {
|
|
306
|
-
menuItemProps.onClick(event as React.MouseEvent);
|
|
307
|
-
}
|
|
308
|
-
};
|
|
309
|
-
|
|
310
|
-
const focusInput = () => {
|
|
311
|
-
if (inputRef.current) {
|
|
312
|
-
inputRef.current.focus();
|
|
313
|
-
}
|
|
314
|
-
};
|
|
315
|
-
|
|
316
|
-
const handleClick = (event: React.MouseEvent) => {
|
|
317
|
-
if (!showingAutocomplete) {
|
|
318
|
-
setShowingAutocomplete(true);
|
|
319
|
-
}
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
const handleFocus = (event: React.FocusEvent) => {
|
|
323
|
-
setIsOpened(true);
|
|
324
|
-
|
|
325
|
-
if (onFocus) {
|
|
326
|
-
onFocus(event);
|
|
327
|
-
}
|
|
328
|
-
};
|
|
329
|
-
|
|
330
|
-
const handleBlur = (event: React.FocusEvent) => {
|
|
331
|
-
if (comboboxRef.current) {
|
|
332
|
-
const target: EventTarget | null = event.relatedTarget;
|
|
333
|
-
|
|
334
|
-
if (target && comboboxRef.current.contains(target as Element)) {
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
setIsOpened(false);
|
|
340
|
-
|
|
341
|
-
if (onBlur) {
|
|
342
|
-
onBlur(event);
|
|
343
|
-
}
|
|
344
|
-
};
|
|
345
|
-
|
|
346
|
-
const resetSearchInput = (): void => {
|
|
347
|
-
setInputValue('');
|
|
348
|
-
focusInput();
|
|
349
|
-
};
|
|
350
|
-
|
|
351
|
-
const getGroupIndex = (itemIndex: number | null) => {
|
|
352
|
-
if (
|
|
353
|
-
itemIndex != null &&
|
|
354
|
-
autocompleteItems &&
|
|
355
|
-
autocompleteItems.length &&
|
|
356
|
-
autocompleteItems[0].hasOwnProperty('header')
|
|
357
|
-
) {
|
|
358
|
-
let count = 0;
|
|
359
|
-
return (autocompleteItems as ComboBoxMenuItemGroup[]).findIndex(groups => {
|
|
360
|
-
count += groups.items.length;
|
|
361
|
-
return count > itemIndex;
|
|
362
|
-
});
|
|
363
|
-
} else {
|
|
364
|
-
return -1;
|
|
365
|
-
}
|
|
366
|
-
};
|
|
367
|
-
|
|
368
|
-
const handleKeyboardShortcuts = (event: React.KeyboardEvent): void => {
|
|
369
|
-
if (event.ctrlKey || event.altKey || event.metaKey || !interactiveAutocompleteItems.length) {
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
const autoCompleteItemCount = interactiveAutocompleteItems.length;
|
|
373
|
-
const firstItem = 0;
|
|
374
|
-
const lastItem = autoCompleteItemCount - 1;
|
|
375
|
-
let nextIndex: number | null = null;
|
|
376
|
-
|
|
377
|
-
setIsOpened(true);
|
|
378
|
-
|
|
379
|
-
switch (event.key) {
|
|
380
|
-
case 'ArrowUp':
|
|
381
|
-
case 'Up': // IE/Edge specific value
|
|
382
|
-
const upIndex =
|
|
383
|
-
selectedAutocompleteIndex !== null ? selectedAutocompleteIndex - 1 : lastItem;
|
|
384
|
-
nextIndex = upIndex < 0 ? lastItem : upIndex;
|
|
385
|
-
event.stopPropagation();
|
|
386
|
-
event.preventDefault();
|
|
387
|
-
break;
|
|
388
|
-
|
|
389
|
-
case 'ArrowDown':
|
|
390
|
-
case 'Down': // IE/Edge specific value
|
|
391
|
-
const downIndex =
|
|
392
|
-
selectedAutocompleteIndex !== null ? selectedAutocompleteIndex + 1 : firstItem;
|
|
393
|
-
nextIndex = downIndex >= autoCompleteItemCount ? firstItem : downIndex;
|
|
394
|
-
event.stopPropagation();
|
|
395
|
-
event.preventDefault();
|
|
396
|
-
break;
|
|
397
|
-
|
|
398
|
-
case 'Escape':
|
|
399
|
-
case 'Esc': // IE/Edge specific value
|
|
400
|
-
resetSearchInput();
|
|
401
|
-
break;
|
|
402
|
-
|
|
403
|
-
case 'Enter':
|
|
404
|
-
if (selectedAutocompleteIndex != null) {
|
|
405
|
-
const item = interactiveAutocompleteItems[selectedAutocompleteIndex];
|
|
406
|
-
handleAutocompleteClick(event, item.props);
|
|
407
|
-
if (item.props.isDisabled || item.props['aria-disabled']) {
|
|
408
|
-
nextIndex = selectedAutocompleteIndex;
|
|
409
|
-
}
|
|
410
|
-
event.stopPropagation();
|
|
411
|
-
event.preventDefault();
|
|
412
|
-
}
|
|
413
|
-
break;
|
|
414
|
-
|
|
415
|
-
default:
|
|
416
|
-
}
|
|
417
|
-
const lastGroupIndex = getGroupIndex(selectedAutocompleteIndex);
|
|
418
|
-
const nextGroupIndex = getGroupIndex(nextIndex);
|
|
419
|
-
setShowGroupText(lastGroupIndex !== nextGroupIndex);
|
|
420
|
-
setSelectedAutocompleteIndex(nextIndex);
|
|
421
|
-
};
|
|
422
|
-
|
|
423
|
-
const handleSearchInputChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
|
|
424
|
-
if (onChange) {
|
|
425
|
-
onChange(event);
|
|
426
|
-
}
|
|
427
|
-
_setValue(event.target.value); // Calling set value directly only for on change event
|
|
428
|
-
};
|
|
429
|
-
|
|
430
|
-
const renderChildren = (inputElement: React.ReactElement<TextInputProps>): React.ReactNode => {
|
|
431
|
-
let cssOverride: CSSObject = {':focus': {zIndex: 2}};
|
|
432
|
-
if (showClearButton) {
|
|
433
|
-
cssOverride = {
|
|
434
|
-
...cssOverride,
|
|
435
|
-
paddingInlineEnd: space.xl,
|
|
436
|
-
};
|
|
437
|
-
}
|
|
438
|
-
const newTextInputProps: Partial<
|
|
439
|
-
TextInputProps &
|
|
440
|
-
React.InputHTMLAttributes<HTMLInputElement> & {ref: React.Ref<HTMLInputElement>}
|
|
441
|
-
> & {css: CSSObject} = {
|
|
442
|
-
type: 'text',
|
|
443
|
-
grow: grow,
|
|
444
|
-
value: value,
|
|
445
|
-
ref: elementRef,
|
|
446
|
-
'aria-autocomplete': 'list',
|
|
447
|
-
'aria-activedescendant':
|
|
448
|
-
selectedAutocompleteIndex !== null
|
|
449
|
-
? getOptionId(componentId, selectedAutocompleteIndex)
|
|
450
|
-
: undefined,
|
|
451
|
-
onClick: handleClick,
|
|
452
|
-
onChange: handleSearchInputChange,
|
|
453
|
-
onKeyDown: handleKeyboardShortcuts,
|
|
454
|
-
onFocus: handleFocus,
|
|
455
|
-
onBlur: handleBlur,
|
|
456
|
-
css: cssOverride,
|
|
457
|
-
role: 'combobox',
|
|
458
|
-
'aria-owns': showingAutocomplete ? `${componentId}-${listBoxIdPart}` : undefined,
|
|
459
|
-
'aria-haspopup': true,
|
|
460
|
-
'aria-expanded': showingAutocomplete,
|
|
461
|
-
};
|
|
462
|
-
const cloneElement = (element: React.ReactElement<TextInputProps>, props: TextInputProps) =>
|
|
463
|
-
jsx(element.type, {
|
|
464
|
-
...element.props,
|
|
465
|
-
...props,
|
|
466
|
-
});
|
|
467
|
-
return cloneElement(inputElement, {...inputElement.props, ...newTextInputProps});
|
|
468
|
-
};
|
|
469
|
-
|
|
470
|
-
return (
|
|
471
|
-
<Container grow={grow} {...elemProps}>
|
|
472
|
-
<InputContainer ref={comboboxRef}>
|
|
473
|
-
{isValidSingleChild(children) && React.Children.map(children, renderChildren)}
|
|
474
|
-
{showClearButton && (
|
|
475
|
-
<ResetButton
|
|
476
|
-
shouldShow={!!value}
|
|
477
|
-
aria-label={clearButtonAriaLabel}
|
|
478
|
-
icon={xSmallIcon}
|
|
479
|
-
variant={clearButtonVariant}
|
|
480
|
-
onClick={resetSearchInput}
|
|
481
|
-
onBlur={handleBlur}
|
|
482
|
-
data-part="combobox-reset-button"
|
|
483
|
-
size="small"
|
|
484
|
-
type="button"
|
|
485
|
-
/>
|
|
486
|
-
)}
|
|
487
|
-
{showingAutocomplete && autocompleteItems && (
|
|
488
|
-
<MenuContainer padding={space.zero} depth={3}>
|
|
489
|
-
<Card.Body>
|
|
490
|
-
<AutocompleteList
|
|
491
|
-
comboboxId={componentId}
|
|
492
|
-
autocompleteItems={autocompleteItems}
|
|
493
|
-
selectedIndex={selectedAutocompleteIndex}
|
|
494
|
-
handleAutocompleteClick={handleAutocompleteClick}
|
|
495
|
-
labelId={formLabelId}
|
|
496
|
-
showGroupText={showGroupText}
|
|
497
|
-
/>
|
|
498
|
-
</Card.Body>
|
|
499
|
-
</MenuContainer>
|
|
500
|
-
)}
|
|
501
|
-
</InputContainer>
|
|
502
|
-
<Status announcementText={announcementText} />
|
|
503
|
-
</Container>
|
|
504
|
-
);
|
|
505
|
-
};
|
package/combobox/lib/Status.tsx
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import {useState, useEffect} from 'react';
|
|
2
|
-
import styled from '@emotion/styled';
|
|
3
|
-
import {accessibleHide} from '@workday/canvas-kit-react/common';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @deprecated ⚠️ `StatusProps` in Labs has been deprecated and will be removed in a future major version. Please use [`Combobox` in Main](https://workday.github.io/canvas-kit/?path=/docs/features-combobox--docs) instead.
|
|
7
|
-
*/
|
|
8
|
-
export interface StatusProps {
|
|
9
|
-
ariaLive?: 'polite' | 'assertive' | 'off';
|
|
10
|
-
role?: 'log' | 'status' | 'alert' | 'progressbar' | 'marquee' | 'timer';
|
|
11
|
-
ariaRelevant?: 'additions' | 'additions text' | 'all' | 'removals' | 'text';
|
|
12
|
-
ariaAtomic?: boolean;
|
|
13
|
-
expireMilliseconds?: number;
|
|
14
|
-
announcementText?: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const Container = styled('div')(accessibleHide);
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @deprecated ⚠️ `Status` in Labs has been deprecated and will be removed in a future major version. Please use [`Combobox` in Main](https://workday.github.io/canvas-kit/?path=/docs/features-combobox--docs) instead.
|
|
21
|
-
*/
|
|
22
|
-
export const Status = ({
|
|
23
|
-
ariaLive = 'polite',
|
|
24
|
-
role = 'status',
|
|
25
|
-
ariaRelevant = 'additions',
|
|
26
|
-
expireMilliseconds = 500,
|
|
27
|
-
announcementText = '',
|
|
28
|
-
ariaAtomic,
|
|
29
|
-
}: StatusProps) => {
|
|
30
|
-
const [displayText, setDisplayText] = useState(announcementText);
|
|
31
|
-
useEffect(() => {
|
|
32
|
-
if (!announcementText) {
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
setDisplayText(announcementText);
|
|
36
|
-
const clearText = setTimeout(() => setDisplayText(''), expireMilliseconds);
|
|
37
|
-
|
|
38
|
-
return () => {
|
|
39
|
-
clearTimeout(clearText);
|
|
40
|
-
};
|
|
41
|
-
}, [announcementText, expireMilliseconds]);
|
|
42
|
-
return (
|
|
43
|
-
<Container
|
|
44
|
-
aria-live={ariaLive}
|
|
45
|
-
role={role}
|
|
46
|
-
aria-relevant={ariaRelevant}
|
|
47
|
-
aria-atomic={ariaAtomic}
|
|
48
|
-
>
|
|
49
|
-
{displayText}
|
|
50
|
-
</Container>
|
|
51
|
-
);
|
|
52
|
-
};
|
package/combobox/package.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../combobox/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./lib/Combobox"), exports);
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { ComboBoxMenuItemGroup } from './Combobox';
|
|
3
|
-
interface AutocompleteListProps {
|
|
4
|
-
/**
|
|
5
|
-
* The autocomplete items of the Combobox. This array of menu items is shown under the text input.
|
|
6
|
-
*/
|
|
7
|
-
autocompleteItems: React.ReactElement<any>[] | ComboBoxMenuItemGroup[];
|
|
8
|
-
/**
|
|
9
|
-
* Index of the active autocomplete item
|
|
10
|
-
*/
|
|
11
|
-
selectedIndex: number | null;
|
|
12
|
-
/**
|
|
13
|
-
* The function called when an autocomplete item is selected
|
|
14
|
-
*/
|
|
15
|
-
handleAutocompleteClick: (event: React.SyntheticEvent<Element, Event>, menuItemProps: any) => void;
|
|
16
|
-
/**
|
|
17
|
-
* The id of the form field.
|
|
18
|
-
*/
|
|
19
|
-
labelId: string;
|
|
20
|
-
/**
|
|
21
|
-
* The id of the combobox.
|
|
22
|
-
*/
|
|
23
|
-
comboboxId: string;
|
|
24
|
-
/**
|
|
25
|
-
* True when group changes via keyboard control
|
|
26
|
-
*/
|
|
27
|
-
showGroupText: boolean;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* @deprecated ⚠️ `AutocompleteList` in Labs has been deprecated and will be removed in a future major version. Please use [`Combobox` in Main](https://workday.github.io/canvas-kit/?path=/docs/features-combobox--docs) instead.
|
|
31
|
-
*/
|
|
32
|
-
export declare const AutocompleteList: ({ autocompleteItems, comboboxId, selectedIndex, handleAutocompleteClick, labelId, showGroupText, }: AutocompleteListProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
33
|
-
export {};
|
|
34
|
-
//# sourceMappingURL=AutocompleteList.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AutocompleteList.d.ts","sourceRoot":"","sources":["../../../../combobox/lib/AutocompleteList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAIhD,OAAO,EAAC,qBAAqB,EAAiD,MAAM,YAAY,CAAC;AAYjG,UAAU,qBAAqB;IAC7B;;OAEG;IACH,iBAAiB,EAAE,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,GAAG,qBAAqB,EAAE,CAAC;IACvE;;OAEG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;OAEG;IACH,uBAAuB,EAAE,CACvB,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,EAC3C,aAAa,EAAE,GAAG,KACf,IAAI,CAAC;IACV;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,aAAa,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,uGAO1B,qBAAqB,mDA+EvB,CAAC"}
|