@jobber/components 4.58.5 → 4.59.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/Combobox/Combobox.d.ts +3 -8
- package/dist/Combobox/Combobox.types.d.ts +71 -44
- package/dist/Combobox/ComboboxProvider.d.ts +12 -4
- package/dist/Combobox/components/ComboboxActivator/ComboboxActivator.d.ts +1 -4
- package/dist/Combobox/components/ComboboxOption/ComboboxOption.d.ts +6 -2
- package/dist/Combobox/components/ComboboxTrigger/ComboboxTrigger.d.ts +2 -6
- package/dist/Combobox/components/ComboboxTrigger/index.d.ts +0 -2
- package/dist/Combobox/hooks/useCombobox.d.ts +15 -0
- package/dist/Combobox/hooks/useComboboxAccessibility.d.ts +1 -1
- package/dist/Combobox/hooks/useComboboxContent.d.ts +1 -6
- package/dist/Combobox/hooks/useComboboxValidation.d.ts +11 -9
- package/dist/Combobox/hooks/useMakeComboboxHandlers.d.ts +7 -0
- package/dist/Combobox/index.js +165 -182
- package/package.json +2 -2
- package/dist/Combobox/components/ComboboxTrigger/ComboboxTriggerButton/ComboboxTriggerButton.d.ts +0 -3
- package/dist/Combobox/components/ComboboxTrigger/ComboboxTriggerChip/ComboboxTriggerChip.d.ts +0 -3
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { ComboboxProps } from "./Combobox.types";
|
|
3
|
-
import { ComboboxContent } from "./components/ComboboxContent";
|
|
4
3
|
import { ComboboxAction } from "./components/ComboboxAction";
|
|
5
|
-
import {
|
|
6
|
-
import { ComboboxOption } from "./components/ComboboxOption";
|
|
4
|
+
import { ComboboxOption as ComboboxOptionComponent } from "./components/ComboboxOption/ComboboxOption";
|
|
7
5
|
import { ComboboxActivator } from "./components/ComboboxActivator";
|
|
8
|
-
export declare function Combobox(
|
|
6
|
+
export declare function Combobox(props: ComboboxProps): JSX.Element;
|
|
9
7
|
export declare namespace Combobox {
|
|
10
|
-
var TriggerButton: typeof ComboboxTriggerButton;
|
|
11
|
-
var TriggerChip: typeof ComboboxTriggerChip;
|
|
12
8
|
var Activator: typeof ComboboxActivator;
|
|
13
|
-
var Content: typeof ComboboxContent;
|
|
14
9
|
var Action: typeof ComboboxAction;
|
|
15
|
-
var Option: typeof
|
|
10
|
+
var Option: typeof ComboboxOptionComponent;
|
|
16
11
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Dispatch, ReactElement, SetStateAction } from "react";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export interface ComboboxProps
|
|
5
|
-
readonly children
|
|
2
|
+
type ComboboxFragment = Iterable<ComboboxNode>;
|
|
3
|
+
type ComboboxNode = ReactElement | ComboboxFragment;
|
|
4
|
+
export interface ComboboxProps {
|
|
5
|
+
readonly children?: ComboboxNode;
|
|
6
6
|
/**
|
|
7
7
|
* When `true`, `Combobox` will allow for multiple selections
|
|
8
8
|
*
|
|
@@ -10,52 +10,48 @@ export interface ComboboxProps extends Partial<Omit<ComboboxContentBaseProps, "o
|
|
|
10
10
|
*/
|
|
11
11
|
readonly multiSelect?: boolean;
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
*/
|
|
15
|
-
readonly label?: string;
|
|
16
|
-
readonly onSelect?: (selection: ComboboxOption[]) => void;
|
|
17
|
-
readonly onClose?: (selection: ComboboxOption[]) => void;
|
|
18
|
-
}
|
|
19
|
-
export interface ComboboxTriggerProps {
|
|
20
|
-
/**
|
|
21
|
-
* The label text of the trigger.
|
|
13
|
+
* Placeholder text to display in the search input. Defaults to "Search".
|
|
22
14
|
*/
|
|
23
|
-
readonly
|
|
24
|
-
}
|
|
25
|
-
export interface ComboboxTriggerButtonProps extends ComboboxTriggerProps, Pick<ButtonProps, "type" | "variation" | "icon" | "iconOnRight"> {
|
|
26
|
-
}
|
|
27
|
-
export type ComboboxTriggerChipProps = ComboboxTriggerProps;
|
|
28
|
-
export interface ComboboxOption {
|
|
15
|
+
readonly searchPlaceholder?: string;
|
|
29
16
|
/**
|
|
30
|
-
*
|
|
17
|
+
* The selected options of the Combobox.
|
|
31
18
|
*/
|
|
32
|
-
|
|
19
|
+
readonly selected: ComboboxOption[];
|
|
33
20
|
/**
|
|
34
|
-
* The
|
|
21
|
+
* The encapsulating noun for the content of the combobox. Used
|
|
22
|
+
* in the empty state, and search placeholder. Should be pluralized.
|
|
35
23
|
*/
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
interface ComboboxCloseProps {
|
|
24
|
+
readonly subjectNoun?: string;
|
|
39
25
|
/**
|
|
40
26
|
* Callback function invoked upon the selection of an option. Provides the selected option(s) as an argument.
|
|
41
27
|
*/
|
|
42
28
|
readonly onSelect: (selection: ComboboxOption[]) => void;
|
|
43
|
-
}
|
|
44
|
-
interface ComboboxSelectProps {
|
|
45
29
|
/**
|
|
46
|
-
* Callback function invoked upon the Combobox menu closing.
|
|
30
|
+
* Callback function invoked upon the Combobox menu closing.
|
|
31
|
+
*/
|
|
32
|
+
readonly onClose?: () => void;
|
|
33
|
+
/**
|
|
34
|
+
* The Chip heading for the trigger
|
|
47
35
|
*/
|
|
48
|
-
readonly
|
|
36
|
+
readonly label?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface ComboboxActivatorProps {
|
|
39
|
+
readonly children: React.ReactElement;
|
|
40
|
+
}
|
|
41
|
+
export interface ComboboxTriggerProps extends Pick<ComboboxContentProps, "selected"> {
|
|
42
|
+
readonly label?: string;
|
|
49
43
|
}
|
|
50
|
-
interface
|
|
44
|
+
export interface ComboboxOption {
|
|
51
45
|
/**
|
|
52
|
-
*
|
|
46
|
+
* A unique identifier for the option.
|
|
53
47
|
*/
|
|
54
|
-
|
|
48
|
+
id: string | number;
|
|
55
49
|
/**
|
|
56
|
-
*
|
|
50
|
+
* The value to be visually displayed in the Combobox options list.
|
|
57
51
|
*/
|
|
58
|
-
|
|
52
|
+
label: string;
|
|
53
|
+
}
|
|
54
|
+
export interface ComboboxContentProps {
|
|
59
55
|
/**
|
|
60
56
|
* Placeholder text to display in the search input. Defaults to "Search".
|
|
61
57
|
*/
|
|
@@ -69,8 +65,47 @@ interface ComboboxContentBaseProps {
|
|
|
69
65
|
* in the empty state, and search placeholder. Should be pluralized.
|
|
70
66
|
*/
|
|
71
67
|
readonly subjectNoun?: string;
|
|
68
|
+
/**
|
|
69
|
+
* Action elements to be displayed at the bottom of the list.
|
|
70
|
+
*/
|
|
71
|
+
readonly actionElements?: ReactElement[];
|
|
72
|
+
/**
|
|
73
|
+
* State setter for the selected options.
|
|
74
|
+
*/
|
|
75
|
+
readonly selectedStateSetter: (selection: ComboboxOption[]) => void;
|
|
76
|
+
/**
|
|
77
|
+
* Callback function to be called when an option is selected.
|
|
78
|
+
*/
|
|
79
|
+
readonly handleSelection: (option: ComboboxOption) => void;
|
|
80
|
+
/**
|
|
81
|
+
* Are multiple selections permitted.
|
|
82
|
+
*/
|
|
83
|
+
readonly multiselect?: boolean;
|
|
84
|
+
/**
|
|
85
|
+
* The current search term.
|
|
86
|
+
*/
|
|
87
|
+
readonly searchValue: string;
|
|
88
|
+
/**
|
|
89
|
+
* Setter for the current search term.
|
|
90
|
+
*/
|
|
91
|
+
readonly setSearchValue: Dispatch<SetStateAction<string>>;
|
|
92
|
+
/**
|
|
93
|
+
* Reference to the wrapping div element of all the Combobox pieces
|
|
94
|
+
*/
|
|
95
|
+
readonly wrapperRef: React.RefObject<HTMLDivElement>;
|
|
96
|
+
/**
|
|
97
|
+
* Is the Combobox open
|
|
98
|
+
*/
|
|
99
|
+
readonly open: boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Setter for the open state of the Combobox.
|
|
102
|
+
*/
|
|
103
|
+
readonly setOpen: (open: boolean) => void;
|
|
104
|
+
/**
|
|
105
|
+
* The full set of options for the Combobox in the shape of data, not elements.
|
|
106
|
+
*/
|
|
107
|
+
readonly options: ComboboxOption[];
|
|
72
108
|
}
|
|
73
|
-
export type ComboboxContentProps = ComboboxContentBaseProps & XOR<ComboboxCloseProps, ComboboxSelectProps>;
|
|
74
109
|
export interface ComboboxSearchProps {
|
|
75
110
|
/**
|
|
76
111
|
* The placeholder for the search input.
|
|
@@ -128,14 +163,6 @@ export interface ComboboxListProps {
|
|
|
128
163
|
* A ref to the list element.
|
|
129
164
|
*/
|
|
130
165
|
readonly optionsListRef: React.RefObject<HTMLUListElement>;
|
|
131
|
-
/**
|
|
132
|
-
* Setter for the first selected element, which is used to scroll the list to the first selected element on re-opening.
|
|
133
|
-
*/
|
|
134
|
-
readonly setFirstSelectedElement: React.Dispatch<SetStateAction<HTMLElement | null>>;
|
|
135
|
-
/**
|
|
136
|
-
* The callback function to call when an option is selected.
|
|
137
|
-
*/
|
|
138
|
-
readonly selectionHandler: (option: ComboboxOption) => void;
|
|
139
166
|
/**
|
|
140
167
|
* The current search term. Used in the no results message.
|
|
141
168
|
*/
|
|
@@ -143,7 +170,7 @@ export interface ComboboxListProps {
|
|
|
143
170
|
/**
|
|
144
171
|
* Determines if it is a single selection or multi selection Combobox.
|
|
145
172
|
*/
|
|
146
|
-
readonly multiselect
|
|
173
|
+
readonly multiselect?: boolean;
|
|
147
174
|
/**
|
|
148
175
|
* The noun to be used in the empty state message.
|
|
149
176
|
*/
|
|
@@ -1,12 +1,20 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { Dispatch, MutableRefObject, SetStateAction } from "react";
|
|
2
|
+
import { ComboboxOption } from "./Combobox.types";
|
|
2
3
|
export declare const ComboboxContext: React.Context<{
|
|
3
|
-
multiselect: boolean;
|
|
4
4
|
open: boolean;
|
|
5
5
|
setOpen: (open: boolean) => void;
|
|
6
|
-
|
|
6
|
+
selected: ComboboxOption[];
|
|
7
|
+
selectionHandler: (option: ComboboxOption) => void;
|
|
8
|
+
handleClose: () => void;
|
|
9
|
+
shouldScroll: MutableRefObject<boolean>;
|
|
7
10
|
}>;
|
|
8
11
|
export interface ComboboxProviderProps {
|
|
9
12
|
readonly children: React.ReactNode;
|
|
10
|
-
readonly
|
|
13
|
+
readonly selected: ComboboxOption[];
|
|
14
|
+
readonly selectionHandler: (option: ComboboxOption) => void;
|
|
15
|
+
readonly open: boolean;
|
|
16
|
+
readonly setOpen: Dispatch<SetStateAction<boolean>>;
|
|
17
|
+
readonly handleClose: () => void;
|
|
18
|
+
readonly shouldScroll: MutableRefObject<boolean>;
|
|
11
19
|
}
|
|
12
20
|
export declare function ComboboxContextProvider(props: ComboboxProviderProps): JSX.Element;
|
|
@@ -1,6 +1,3 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
|
|
3
|
-
readonly children: React.ReactElement;
|
|
4
|
-
}
|
|
2
|
+
import { ComboboxActivatorProps } from "../../Combobox.types";
|
|
5
3
|
export declare function ComboboxActivator(props: ComboboxActivatorProps): React.ReactElement<any, string | React.JSXElementConstructor<any>>;
|
|
6
|
-
export {};
|
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export interface ComboboxOptionProps {
|
|
3
|
+
readonly id: string | number;
|
|
4
|
+
readonly label: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function ComboboxOption(props: ComboboxOptionProps): JSX.Element;
|
|
@@ -1,7 +1,3 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
readonly label: string;
|
|
5
|
-
}
|
|
6
|
-
export declare function ComboboxTrigger({ selected, ...props }: ComboboxTriggerProps): JSX.Element;
|
|
7
|
-
export {};
|
|
2
|
+
import { ComboboxTriggerProps } from "../../Combobox.types";
|
|
3
|
+
export declare function ComboboxTrigger({ label, selected, }: ComboboxTriggerProps): JSX.Element;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React, { Dispatch, MutableRefObject } from "react";
|
|
2
|
+
import { UseMakeComboboxHandlersReturn } from "./useMakeComboboxHandlers";
|
|
3
|
+
import { ComboboxOption } from "../Combobox.types";
|
|
4
|
+
type UseComboboxReturn = {
|
|
5
|
+
wrapperRef: React.RefObject<HTMLDivElement>;
|
|
6
|
+
searchValue: string;
|
|
7
|
+
setSearchValue: Dispatch<React.SetStateAction<string>>;
|
|
8
|
+
open: boolean;
|
|
9
|
+
setOpen: Dispatch<React.SetStateAction<boolean>>;
|
|
10
|
+
selectedOptions: ComboboxOption[];
|
|
11
|
+
selectedStateSetter: (selection: ComboboxOption[]) => void;
|
|
12
|
+
shouldScroll: MutableRefObject<boolean>;
|
|
13
|
+
} & UseMakeComboboxHandlersReturn;
|
|
14
|
+
export declare function useCombobox(selected: ComboboxOption[], onSelect: (selection: ComboboxOption[]) => void, onClose?: () => void, multiSelect?: boolean): UseComboboxReturn;
|
|
15
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { ComboboxOption } from "../Combobox.types";
|
|
3
|
-
export declare function useComboboxAccessibility(selectionCallback: (selection: ComboboxOption) => void, filteredOptions: ComboboxOption[], optionsListRef: React.RefObject<HTMLUListElement>, open: boolean,
|
|
3
|
+
export declare function useComboboxAccessibility(selectionCallback: (selection: ComboboxOption) => void, filteredOptions: ComboboxOption[], optionsListRef: React.RefObject<HTMLUListElement>, open: boolean, wrapperRef: React.RefObject<HTMLDivElement>): {
|
|
4
4
|
popperRef: React.RefObject<HTMLDivElement>;
|
|
5
5
|
popperStyles: {
|
|
6
6
|
[key: string]: React.CSSProperties;
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { ComboboxOption } from "../Combobox.types";
|
|
3
3
|
interface useComboboxContent {
|
|
4
|
-
searchValue: string;
|
|
5
|
-
setSearchValue: React.Dispatch<React.SetStateAction<string>>;
|
|
6
|
-
setFirstSelectedElement: React.Dispatch<React.SetStateAction<HTMLElement | null>>;
|
|
7
4
|
filteredOptions: ComboboxOption[];
|
|
8
5
|
optionsListRef: React.RefObject<HTMLUListElement>;
|
|
9
|
-
selectedOptions: ComboboxOption[];
|
|
10
|
-
optionsSelectionHandler: (selected: ComboboxOption[]) => void;
|
|
11
6
|
}
|
|
12
|
-
export declare function useComboboxContent(options: ComboboxOption[], open: boolean, selected: ComboboxOption[],
|
|
7
|
+
export declare function useComboboxContent(options: ComboboxOption[], open: boolean, selected: ComboboxOption[], searchValue: string): useComboboxContent;
|
|
13
8
|
export {};
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { ReactElement
|
|
2
|
-
import {
|
|
3
|
-
export declare const COMBOBOX_TRIGGER_COUNT_ERROR_MESSAGE = "Combobox
|
|
4
|
-
export declare
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
optionElements: ReactElement<ComboboxOptionProps>[];
|
|
9
|
-
actionElements: ReactElement<ComboboxActionProps>[];
|
|
1
|
+
import { ReactElement } from "react";
|
|
2
|
+
import { ComboboxProps } from "../Combobox.types";
|
|
3
|
+
export declare const COMBOBOX_TRIGGER_COUNT_ERROR_MESSAGE = "Combobox must have exactly one Trigger element";
|
|
4
|
+
export declare function useComboboxValidation(children?: ComboboxProps["children"]): {
|
|
5
|
+
triggerElement?: ReactElement;
|
|
6
|
+
optionElements?: ReactElement[];
|
|
7
|
+
actionElements?: ReactElement[];
|
|
10
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* Return all instances child component that matches the `type` provided
|
|
11
|
+
*/
|
|
12
|
+
export declare function getCompoundComponents<T>(type: ReactElement<T>["type"], children?: ComboboxProps["children"]): ReactElement<T>[];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ComboboxOption } from "../Combobox.types";
|
|
3
|
+
export interface UseMakeComboboxHandlersReturn {
|
|
4
|
+
handleClose: () => void;
|
|
5
|
+
handleSelection: (selection: ComboboxOption) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare function useMakeComboboxHandlers(setOpen: (open: boolean) => void, setSearchValue: (searchValue: string) => void, selectedOptions: ComboboxOption[], shouldScroll: React.MutableRefObject<boolean>, selectedStateSetter: (selected: ComboboxOption[]) => void, multiSelect?: boolean, onClose?: () => void): UseMakeComboboxHandlersReturn;
|
package/dist/Combobox/index.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var tslib_es6 = require('../tslib.es6-5b8768b7.js');
|
|
6
5
|
var React = require('react');
|
|
7
6
|
var classnames = require('classnames');
|
|
8
7
|
var ReactDOM = require('react-dom');
|
|
@@ -16,8 +15,8 @@ var useFocusTrap = require('@jobber/hooks/useFocusTrap');
|
|
|
16
15
|
var reactPopper = require('react-popper');
|
|
17
16
|
var useOnKeyDown = require('@jobber/hooks/useOnKeyDown');
|
|
18
17
|
var Chip = require('../Chip-f8b8fd89.js');
|
|
19
|
-
var useAssert = require('@jobber/hooks/useAssert');
|
|
20
18
|
require('@jobber/design');
|
|
19
|
+
var useAssert = require('@jobber/hooks/useAssert');
|
|
21
20
|
require('react-router-dom');
|
|
22
21
|
require('@jobber/hooks/useInView');
|
|
23
22
|
require('../Avatar-1aa30ee1.js');
|
|
@@ -63,24 +62,40 @@ function ComboboxContentSearch(props) {
|
|
|
63
62
|
}
|
|
64
63
|
}
|
|
65
64
|
|
|
66
|
-
var css_248z$4 = ".SgMzjOcdE-E- {\n position: relative;\n padding: calc(16px / 2) 0;\n padding: var(--space-small) 0;\n}\n\n.TwoTCjgcssc- {\n display: -ms-flexbox;\n display: flex;\n max-height: calc((16px / 2) * 33.33);\n max-height: calc(calc(16px / 2) * 33.33);\n max-height: calc(var(--space-small) * 33.33);\n margin: 0;\n padding: 0;\n overflow: scroll;\n list-style: none;\n -ms-flex-direction: column;\n flex-direction: column;\n gap: calc(16px / 4);\n gap: var(--space-smaller);\n}\n\n.
|
|
67
|
-
var styles$4 = {"container":"SgMzjOcdE-E-","optionsList":"TwoTCjgcssc-","
|
|
65
|
+
var css_248z$4 = ".SgMzjOcdE-E- {\n position: relative;\n padding: calc(16px / 2) 0;\n padding: var(--space-small) 0;\n}\n\n.TwoTCjgcssc- {\n display: -ms-flexbox;\n display: flex;\n max-height: calc((16px / 2) * 33.33);\n max-height: calc(calc(16px / 2) * 33.33);\n max-height: calc(var(--space-small) * 33.33);\n margin: 0;\n padding: 0;\n overflow: scroll;\n list-style: none;\n -ms-flex-direction: column;\n flex-direction: column;\n gap: calc(16px / 4);\n gap: var(--space-smaller);\n}\n\n._8T5M7MGwCRE-,\n._4y5NXkNeIQM- {\n padding: calc(16px / 2) calc(16px * 1);\n padding: var(--space-small) var(--space-base);\n}\n\n.SgMzjOcdE-E-::after {\n content: \"\";\n display: block;\n position: absolute;\n right: 0;\n bottom: calc(16px / 2);\n bottom: var(--space-small);\n left: 0;\n height: calc(16px * 1);\n height: var(--space-base);\n background: linear-gradient(\n 180deg,\n rgba(255, 255, 255, 0) 0%,\n rgb(255, 255, 255) 100%\n );\n}\n\n.SgMzjOcdE-E-::before {\n content: \"\";\n display: block;\n position: absolute;\n top: calc(16px / 2);\n top: var(--space-small);\n right: 0;\n left: 0;\n height: calc(16px * 1);\n height: var(--space-base);\n background: linear-gradient(\n to bottom,\n rgba(255, 255, 255, 1),\n rgba(255, 255, 255, 0)\n );\n}\n";
|
|
66
|
+
var styles$4 = {"container":"SgMzjOcdE-E-","optionsList":"TwoTCjgcssc-","filterMessage":"_8T5M7MGwCRE-","emptyStateMessage":"_4y5NXkNeIQM-"};
|
|
68
67
|
styleInject_es.styleInject(css_248z$4);
|
|
69
68
|
|
|
69
|
+
var css_248z$3 = "._5QdRGmaNHvc- {\n display: -ms-flexbox;\n display: flex;\n min-height: calc((calc(16px * 3) - calc(16px / 4)));\n min-height: calc((var(--space-largest) - var(--space-smaller)));\n box-sizing: border-box;\n margin: 0 calc(16px / 2);\n margin: 0 var(--space-small);\n padding: calc(16px / 2);\n padding: var(--space-small);\n border-radius: calc(16px / 4);\n border-radius: var(--radius-large);\n color: rgb(1, 41, 57);\n color: var(--color-heading);\n font-weight: 500;\n cursor: pointer;\n transition: all 200ms;\n transition: all var(--timing-base);\n -ms-flex-pack: justify;\n justify-content: space-between;\n -ms-flex-align: center;\n align-items: center;\n}\n\n._5QdRGmaNHvc-:hover,\n._5QdRGmaNHvc-:focus {\n background-color: rgb(244, 244, 244);\n background-color: var(--color-surface--background);\n}\n\n._5QdRGmaNHvc-:focus {\n box-shadow: 0px 0px calc(16px / 4) calc(16px / 8)\n rgb(231, 213, 87);\n box-shadow: var(--shadow-focus);\n}\n";
|
|
70
|
+
var styles$3 = {"option":"_5QdRGmaNHvc-"};
|
|
71
|
+
styleInject_es.styleInject(css_248z$3);
|
|
72
|
+
|
|
73
|
+
const ComboboxContext = React__default["default"].createContext({});
|
|
74
|
+
function ComboboxContextProvider(props) {
|
|
75
|
+
return (React__default["default"].createElement(ComboboxContext.Provider, { value: {
|
|
76
|
+
open: props.open,
|
|
77
|
+
setOpen: props.setOpen,
|
|
78
|
+
selected: props.selected,
|
|
79
|
+
selectionHandler: props.selectionHandler,
|
|
80
|
+
handleClose: props.handleClose,
|
|
81
|
+
shouldScroll: props.shouldScroll,
|
|
82
|
+
} }, props.children));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function ComboboxOption(props) {
|
|
86
|
+
const { selected, selectionHandler } = React.useContext(ComboboxContext);
|
|
87
|
+
const isSelected = selected.some(selection => selection.id.toString() === props.id.toString());
|
|
88
|
+
return (React__default["default"].createElement("li", { key: props.id, tabIndex: -1, "data-selected": isSelected, role: "option", "aria-selected": isSelected, onClick: () => selectionHandler &&
|
|
89
|
+
selectionHandler({ id: props.id, label: props.label }), className: classnames__default["default"](styles$3.option) },
|
|
90
|
+
props.label,
|
|
91
|
+
isSelected && React__default["default"].createElement(Icon.Icon, { name: "checkmark", color: "blue" })));
|
|
92
|
+
}
|
|
93
|
+
|
|
70
94
|
function ComboboxContentList(props) {
|
|
71
|
-
let hasSeenFirstSelected = false;
|
|
72
95
|
return (React__default["default"].createElement("div", { className: styles$4.container },
|
|
73
96
|
!props.showEmptyState && props.options.length > 0 && (React__default["default"].createElement("ul", { className: styles$4.optionsList, role: "listbox", "aria-multiselectable": props.multiselect, ref: props.optionsListRef }, !props.showEmptyState &&
|
|
74
97
|
props.options.map(option => {
|
|
75
|
-
|
|
76
|
-
return (React__default["default"].createElement("li", { ref: listItem => {
|
|
77
|
-
if (isSelected && !hasSeenFirstSelected) {
|
|
78
|
-
props.setFirstSelectedElement(listItem);
|
|
79
|
-
hasSeenFirstSelected = true;
|
|
80
|
-
}
|
|
81
|
-
}, key: option.id, tabIndex: -1, role: "option", "aria-selected": isSelected, onClick: () => props.selectionHandler(option), className: classnames__default["default"](styles$4.option) },
|
|
82
|
-
option.label,
|
|
83
|
-
isSelected && React__default["default"].createElement(Icon.Icon, { name: "checkmark", color: "blue" })));
|
|
98
|
+
return (React__default["default"].createElement(ComboboxOption, { key: option.id, id: option.id, label: option.label }));
|
|
84
99
|
}))),
|
|
85
100
|
!props.showEmptyState && props.options.length === 0 && (React__default["default"].createElement("div", { className: styles$4.filterMessage },
|
|
86
101
|
React__default["default"].createElement(Text.Text, { variation: "subdued" },
|
|
@@ -96,9 +111,9 @@ function getZeroIndexStateText(subjectNoun) {
|
|
|
96
111
|
return "No options yet";
|
|
97
112
|
}
|
|
98
113
|
|
|
99
|
-
var css_248z$
|
|
100
|
-
var styles$
|
|
101
|
-
styleInject_es.styleInject(css_248z$
|
|
114
|
+
var css_248z$2 = ".Q-mwo-g5Fi8- {\n display: -ms-flexbox;\n display: flex;\n padding: calc(16px * 1) calc(16px / 2) 0 calc(16px * 1);\n padding: var(--space-base) var(--space-small) 0 var(--space-base);\n -ms-flex-pack: justify;\n justify-content: space-between;\n gap: calc(16px / 4);\n gap: var(--space-smaller);\n}\n";
|
|
115
|
+
var styles$2 = {"header":"Q-mwo-g5Fi8-"};
|
|
116
|
+
styleInject_es.styleInject(css_248z$2);
|
|
102
117
|
|
|
103
118
|
function ComboboxContentHeader(props) {
|
|
104
119
|
const hasSelected = props.selectedCount > 0;
|
|
@@ -106,7 +121,7 @@ function ComboboxContentHeader(props) {
|
|
|
106
121
|
const label = getLabel(hasSelected, props.selectedCount, props.subjectNoun);
|
|
107
122
|
const handleSelectAll = hasSelected ? props.onClearAll : props.onSelectAll;
|
|
108
123
|
const showAction = hasSelected || props.hasOptionsVisible;
|
|
109
|
-
return (React__default["default"].createElement("div", { className: styles$
|
|
124
|
+
return (React__default["default"].createElement("div", { className: styles$2.header, "data-testid": "ATL-Combobox-Header" },
|
|
110
125
|
React__default["default"].createElement(Typography.Typography, { textColor: "heading", fontWeight: "semiBold" }, label),
|
|
111
126
|
showAction && (React__default["default"].createElement(Button.Button, { size: "small", label: actionLabel, type: "tertiary", onClick: handleSelectAll }))));
|
|
112
127
|
}
|
|
@@ -120,58 +135,38 @@ function getLabel(hasSelected, count, subjectNoun) {
|
|
|
120
135
|
return "Select";
|
|
121
136
|
}
|
|
122
137
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
styleInject_es.styleInject(css_248z$2);
|
|
126
|
-
|
|
127
|
-
const ComboboxContext = React__default["default"].createContext({});
|
|
128
|
-
function ComboboxContextProvider(props) {
|
|
129
|
-
const multiselect = props.multiselect || false;
|
|
130
|
-
const [open, setOpen] = React.useState(false);
|
|
131
|
-
const wrapperRef = React.useRef(null);
|
|
132
|
-
return (React__default["default"].createElement(ComboboxContext.Provider, { value: { multiselect, open, setOpen, wrapperRef } },
|
|
133
|
-
React__default["default"].createElement("div", { ref: wrapperRef },
|
|
134
|
-
open && (React__default["default"].createElement("div", { className: styles$2.overlay, onClick: () => setOpen(false), "data-testid": "ATL-Combobox-Overlay" })),
|
|
135
|
-
props.children)));
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function useComboboxContent(options, open, selected, onClose, onSelect) {
|
|
139
|
-
const [searchValue, setSearchValue] = React.useState("");
|
|
140
|
-
const [firstSelectedElement, setFirstSelectedElement] = React.useState(null);
|
|
138
|
+
function useComboboxContent(options, open, selected, searchValue) {
|
|
139
|
+
const { shouldScroll } = React.useContext(ComboboxContext);
|
|
141
140
|
const optionsListRef = React.useRef(null);
|
|
142
141
|
const filteredOptions = options.filter(option => option.label.toLowerCase().includes(searchValue.toLowerCase()));
|
|
143
|
-
const [internalSelected, setInternalSelected] = React.useState(selected);
|
|
144
|
-
const selectedOptions = onClose ? internalSelected : selected;
|
|
145
|
-
const optionsSelectionHandler = onSelect ? onSelect : setInternalSelected;
|
|
146
|
-
React.useEffect(() => {
|
|
147
|
-
if (!open && onClose) {
|
|
148
|
-
onClose(selectedOptions);
|
|
149
|
-
}
|
|
150
|
-
}, [open, onClose, selectedOptions]);
|
|
151
142
|
React.useEffect(() => {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
143
|
+
var _a;
|
|
144
|
+
if (open && shouldScroll.current && optionsListRef.current) {
|
|
145
|
+
const firstSelected = Array.from((_a = optionsListRef === null || optionsListRef === void 0 ? void 0 : optionsListRef.current) === null || _a === void 0 ? void 0 : _a.children).find(child => {
|
|
146
|
+
if (child instanceof HTMLElement) {
|
|
147
|
+
return child.dataset.selected === "true";
|
|
148
|
+
}
|
|
155
149
|
});
|
|
150
|
+
scrollToFirstSelected(firstSelected, shouldScroll);
|
|
156
151
|
}
|
|
157
|
-
}, [open,
|
|
158
|
-
React.useEffect(() => {
|
|
159
|
-
if (selectedOptions.length === 0) {
|
|
160
|
-
setFirstSelectedElement(null);
|
|
161
|
-
}
|
|
162
|
-
}, [selectedOptions]);
|
|
152
|
+
}, [open, selected]);
|
|
163
153
|
return {
|
|
164
|
-
searchValue,
|
|
165
|
-
setSearchValue,
|
|
166
|
-
setFirstSelectedElement,
|
|
167
154
|
filteredOptions,
|
|
168
155
|
optionsListRef,
|
|
169
|
-
selectedOptions,
|
|
170
|
-
optionsSelectionHandler,
|
|
171
156
|
};
|
|
172
157
|
}
|
|
158
|
+
function scrollToFirstSelected(firstSelected, shouldScroll) {
|
|
159
|
+
if (firstSelected) {
|
|
160
|
+
firstSelected.scrollIntoView({
|
|
161
|
+
block: "nearest",
|
|
162
|
+
});
|
|
163
|
+
shouldScroll.current = false;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
173
166
|
|
|
174
|
-
|
|
167
|
+
// eslint-disable-next-line max-statements
|
|
168
|
+
function useComboboxAccessibility(selectionCallback, filteredOptions, optionsListRef, open, wrapperRef) {
|
|
169
|
+
const { handleClose } = React.useContext(ComboboxContext);
|
|
175
170
|
const hasOptionsVisible = open && filteredOptions.length > 0;
|
|
176
171
|
const focusedIndex = React.useRef(null);
|
|
177
172
|
useRefocusOnActivator.useRefocusOnActivator(open);
|
|
@@ -202,7 +197,7 @@ function useComboboxAccessibility(selectionCallback, filteredOptions, optionsLis
|
|
|
202
197
|
}, [open, optionsListRef, filteredOptions]);
|
|
203
198
|
useOnKeyDown.useOnKeyDown(() => {
|
|
204
199
|
if (open) {
|
|
205
|
-
|
|
200
|
+
handleClose();
|
|
206
201
|
}
|
|
207
202
|
}, "Escape");
|
|
208
203
|
function handleContentKeydown(event) {
|
|
@@ -248,43 +243,21 @@ function useComboboxAccessibility(selectionCallback, filteredOptions, optionsLis
|
|
|
248
243
|
}
|
|
249
244
|
|
|
250
245
|
function ComboboxContent(props) {
|
|
251
|
-
const { open, setOpen, wrapperRef, multiselect } = React__default["default"].useContext(ComboboxContext);
|
|
252
246
|
const optionsExist = props.options.length > 0;
|
|
253
|
-
const {
|
|
254
|
-
const { popperRef, popperStyles, attributes } = useComboboxAccessibility(handleSelection, filteredOptions, optionsListRef, open,
|
|
255
|
-
const template = (React__default["default"].createElement("div", Object.assign({ ref: popperRef, id: "ATL-Combobox-Content", "data-testid": "ATL-Combobox-Content", tabIndex: 0, className: classnames__default["default"](styles$6.content, { [styles$6.hidden]: !open }), style: popperStyles.popper }, attributes.popper),
|
|
256
|
-
React__default["default"].createElement(ComboboxContentSearch, { open: open, placeholder: props.subjectNoun, searchValue: searchValue, setSearchValue: setSearchValue }),
|
|
257
|
-
multiselect && optionsExist && (React__default["default"].createElement(ComboboxContentHeader, { hasOptionsVisible: filteredOptions.length > 0, subjectNoun: props.subjectNoun, selectedCount:
|
|
258
|
-
|
|
247
|
+
const { filteredOptions, optionsListRef } = useComboboxContent(props.options, props.open, props.selected, props.searchValue);
|
|
248
|
+
const { popperRef, popperStyles, attributes } = useComboboxAccessibility(props.handleSelection, filteredOptions, optionsListRef, props.open, props.wrapperRef);
|
|
249
|
+
const template = (React__default["default"].createElement("div", Object.assign({ ref: popperRef, id: "ATL-Combobox-Content", "data-testid": "ATL-Combobox-Content", tabIndex: 0, className: classnames__default["default"](styles$6.content, { [styles$6.hidden]: !props.open }), style: popperStyles.popper }, attributes.popper),
|
|
250
|
+
React__default["default"].createElement(ComboboxContentSearch, { open: props.open, placeholder: props.subjectNoun, searchValue: props.searchValue, setSearchValue: props.setSearchValue }),
|
|
251
|
+
props.multiselect && optionsExist && (React__default["default"].createElement(ComboboxContentHeader, { hasOptionsVisible: filteredOptions.length > 0, subjectNoun: props.subjectNoun, selectedCount: props.selected.length, onClearAll: () => {
|
|
252
|
+
props.selectedStateSetter([]);
|
|
259
253
|
}, onSelectAll: () => {
|
|
260
|
-
|
|
254
|
+
props.selectedStateSetter(filteredOptions);
|
|
261
255
|
} })),
|
|
262
|
-
React__default["default"].createElement(ComboboxContentList, { multiselect: multiselect, showEmptyState: !optionsExist, options: filteredOptions, selected:
|
|
263
|
-
props.
|
|
256
|
+
React__default["default"].createElement(ComboboxContentList, { multiselect: props.multiselect, showEmptyState: !optionsExist, options: filteredOptions, selected: props.selected, optionsListRef: optionsListRef, searchValue: props.searchValue, subjectNoun: props.subjectNoun }),
|
|
257
|
+
props.actionElements && (React__default["default"].createElement("div", { className: styles$6.actions, role: "group" }, props.actionElements.map((child, index, childrenArray) => (React__default["default"].createElement("div", { key: index, className: classnames__default["default"]({
|
|
264
258
|
[styles$6.actionPadding]: index === childrenArray.length - 1,
|
|
265
259
|
}) }, child)))))));
|
|
266
260
|
return ReactDOM__default["default"].createPortal(template, document.body);
|
|
267
|
-
function handleSelection(selection) {
|
|
268
|
-
if (multiselect) {
|
|
269
|
-
handleMultiSelect(optionsSelectionHandler, selectedOptions, selection);
|
|
270
|
-
}
|
|
271
|
-
else {
|
|
272
|
-
handleSingleSelect(optionsSelectionHandler, selection);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
function handleSingleSelect(selectCallback, selection) {
|
|
276
|
-
selectCallback([selection]);
|
|
277
|
-
setSearchValue("");
|
|
278
|
-
setOpen(false);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
function handleMultiSelect(selectCallback, selected, selection) {
|
|
282
|
-
if (selected.some(s => s.id === selection.id)) {
|
|
283
|
-
selectCallback(selected.filter(s => s.id !== selection.id));
|
|
284
|
-
}
|
|
285
|
-
else {
|
|
286
|
-
selectCallback([...selected, selection]);
|
|
287
|
-
}
|
|
288
261
|
}
|
|
289
262
|
|
|
290
263
|
var css_248z$1 = ".Ow9wSNnGP-g- {\n width: 100%;\n box-sizing: border-box;\n padding: 0 calc(16px / 2);\n padding: 0 var(--space-small);\n background-color: rgba(255, 255, 255, 1);\n background-color: var(--color-surface);\n}\n\n.ncp0nKHQ7d8- {\n position: relative;\n width: 100%;\n min-height: calc((calc(16px * 3) - calc(16px / 2)));\n min-height: calc((var(--space-largest) - var(--space-small)));\n padding: calc(16px / 2) 0;\n padding: var(--space-small) 0;\n border: none;\n border-radius: calc(16px / 4);\n border-radius: var(--radius-large);\n text-align: left;\n background-color: rgba(255, 255, 255, 1);\n background-color: var(--color-surface);\n cursor: pointer;\n transition: all 200ms;\n transition: all var(--timing-base);\n}\n\n.ncp0nKHQ7d8-:focus {\n box-shadow: 0px 0px calc(16px / 4) calc(16px / 8)\n rgb(231, 213, 87);\n box-shadow: var(--shadow-focus);\n background-color: rgb(244, 244, 244);\n background-color: var(--color-surface--background);\n}\n\n.ncp0nKHQ7d8-:hover {\n background-color: rgb(244, 244, 244);\n background-color: var(--color-surface--background);\n}\n\n.ncp0nKHQ7d8- span {\n margin-left: calc(16px / 2);\n margin-left: var(--space-small);\n}\n";
|
|
@@ -297,127 +270,137 @@ function ComboboxAction(props) {
|
|
|
297
270
|
React__default["default"].createElement(Typography.Typography, { element: "span", size: "base", textColor: "green", fontWeight: "semiBold" }, props.label))));
|
|
298
271
|
}
|
|
299
272
|
|
|
300
|
-
function
|
|
301
|
-
const { open, setOpen } = React__default["default"].useContext(ComboboxContext);
|
|
302
|
-
|
|
273
|
+
function ComboboxTrigger({ label = "Select", selected, }) {
|
|
274
|
+
const { handleClose, open, setOpen } = React__default["default"].useContext(ComboboxContext);
|
|
275
|
+
const hasSelection = selected.length;
|
|
276
|
+
const selectedLabel = selected.map(option => option.label).join(", ");
|
|
277
|
+
return (React__default["default"].createElement(Chip.Chip, { variation: hasSelection ? "base" : "subtle", label: hasSelection ? selectedLabel : "", heading: label, onClick: () => {
|
|
278
|
+
if (open) {
|
|
279
|
+
handleClose();
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
setOpen(true);
|
|
283
|
+
}
|
|
284
|
+
}, role: "combobox" }, !hasSelection && (React__default["default"].createElement(Chip.Chip.Suffix, null,
|
|
285
|
+
React__default["default"].createElement(Icon.Icon, { name: "add", size: "small" })))));
|
|
303
286
|
}
|
|
304
287
|
|
|
305
|
-
var css_248z = ".
|
|
306
|
-
var styles = {"
|
|
288
|
+
var css_248z = ".W8qMZnORYxI- {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 6;\n z-index: var(--elevation-menu);\n background-color: transparent;\n}\n\n._-0dkolvLF-Y- {\n display: inline-block;\n}\n";
|
|
289
|
+
var styles = {"overlay":"W8qMZnORYxI-","wrapper":"_-0dkolvLF-Y-"};
|
|
307
290
|
styleInject_es.styleInject(css_248z);
|
|
308
291
|
|
|
309
|
-
function
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
292
|
+
function useMakeComboboxHandlers(setOpen, setSearchValue, selectedOptions, shouldScroll, selectedStateSetter, multiSelect, onClose) {
|
|
293
|
+
const handleClose = React.useCallback(() => {
|
|
294
|
+
setOpen(false);
|
|
295
|
+
setSearchValue("");
|
|
296
|
+
onClose && onClose();
|
|
297
|
+
if (selectedOptions.length > 0) {
|
|
298
|
+
shouldScroll.current = true;
|
|
299
|
+
}
|
|
300
|
+
}, [setOpen, setSearchValue, onClose, selectedOptions.length]);
|
|
301
|
+
const handleSelection = React.useCallback((selection) => {
|
|
302
|
+
if (multiSelect) {
|
|
303
|
+
handleMultiSelect(selectedStateSetter, selectedOptions, selection);
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
handleSingleSelect(selectedStateSetter, selection);
|
|
307
|
+
}
|
|
308
|
+
}, [multiSelect, selectedStateSetter, selectedOptions]);
|
|
309
|
+
const handleSingleSelect = React.useCallback((selectCallback, selection) => {
|
|
310
|
+
selectCallback([selection]);
|
|
311
|
+
handleClose();
|
|
312
|
+
}, []);
|
|
313
|
+
return {
|
|
314
|
+
handleClose,
|
|
315
|
+
handleSelection,
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
function handleMultiSelect(selectCallback, selected, selection) {
|
|
319
|
+
if (selected.some(s => s.id === selection.id)) {
|
|
320
|
+
selectCallback(selected.filter(s => s.id !== selection.id));
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
selectCallback([...selected, selection]);
|
|
324
|
+
}
|
|
317
325
|
}
|
|
318
326
|
|
|
319
|
-
function
|
|
320
|
-
|
|
321
|
-
const
|
|
322
|
-
const
|
|
323
|
-
const
|
|
324
|
-
const
|
|
325
|
-
return
|
|
326
|
-
|
|
327
|
+
function useCombobox(selected, onSelect, onClose, multiSelect) {
|
|
328
|
+
const wrapperRef = React.useRef(null);
|
|
329
|
+
const shouldScroll = React.useRef(false);
|
|
330
|
+
const [open, setOpen] = React.useState(false);
|
|
331
|
+
const [searchValue, setSearchValue] = React.useState("");
|
|
332
|
+
const { handleClose, handleSelection } = useMakeComboboxHandlers(setOpen, setSearchValue, selected, shouldScroll, onSelect, multiSelect, onClose);
|
|
333
|
+
return {
|
|
334
|
+
wrapperRef,
|
|
335
|
+
searchValue,
|
|
336
|
+
setSearchValue,
|
|
337
|
+
open,
|
|
338
|
+
setOpen,
|
|
339
|
+
selectedOptions: selected,
|
|
340
|
+
selectedStateSetter: onSelect,
|
|
341
|
+
shouldScroll,
|
|
342
|
+
handleClose,
|
|
343
|
+
handleSelection,
|
|
344
|
+
};
|
|
327
345
|
}
|
|
328
346
|
|
|
329
347
|
function ComboboxActivator(props) {
|
|
330
|
-
const { open, setOpen } = React__default["default"].useContext(ComboboxContext);
|
|
348
|
+
const { handleClose, open, setOpen } = React__default["default"].useContext(ComboboxContext);
|
|
331
349
|
if (props.children.type === Button.Button || props.children.type === Chip.Chip) {
|
|
332
350
|
return React__default["default"].cloneElement(props.children, {
|
|
333
351
|
role: "combobox",
|
|
334
|
-
onClick: () =>
|
|
352
|
+
onClick: () => {
|
|
353
|
+
if (open) {
|
|
354
|
+
handleClose();
|
|
355
|
+
}
|
|
356
|
+
else {
|
|
357
|
+
setOpen(true);
|
|
358
|
+
}
|
|
359
|
+
},
|
|
335
360
|
});
|
|
336
361
|
}
|
|
337
362
|
return props.children;
|
|
338
363
|
}
|
|
339
364
|
|
|
340
|
-
|
|
341
|
-
function ComboboxOption(_) {
|
|
342
|
-
useAssert.useAssert(true, "Combobox.Option can only be used inside a Combobox component");
|
|
343
|
-
return null;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
const COMBOBOX_TRIGGER_COUNT_ERROR_MESSAGE = "Combobox can only have one Trigger or Activator element";
|
|
347
|
-
const COMBOBOX_OPTION_AND_CONTENT_EXISTS_ERROR = "Combobox prefers using Combobox.Option and Combobox.Action as the direct child of Combobox instead of Combobox.Content";
|
|
365
|
+
const COMBOBOX_TRIGGER_COUNT_ERROR_MESSAGE = "Combobox must have exactly one Trigger element";
|
|
348
366
|
function useComboboxValidation(children) {
|
|
349
|
-
const
|
|
350
|
-
|
|
351
|
-
const
|
|
352
|
-
const
|
|
353
|
-
|
|
354
|
-
if (isTriggerElement(child)) {
|
|
355
|
-
if (triggerElement) {
|
|
356
|
-
multipleTriggersFound = true;
|
|
357
|
-
}
|
|
358
|
-
triggerElement = child;
|
|
359
|
-
}
|
|
360
|
-
if (isContentElement(child)) {
|
|
361
|
-
contentElement = child;
|
|
362
|
-
}
|
|
363
|
-
if (isOptionElement(child)) {
|
|
364
|
-
optionElements.push(child);
|
|
365
|
-
}
|
|
366
|
-
if (isActionElement(child)) {
|
|
367
|
-
actionElements.push(child);
|
|
368
|
-
}
|
|
369
|
-
});
|
|
370
|
-
useAssert.useAssert(multipleTriggersFound, COMBOBOX_TRIGGER_COUNT_ERROR_MESSAGE);
|
|
371
|
-
useAssert.useAssert(Boolean((optionElements.length || actionElements.length) && contentElement), COMBOBOX_OPTION_AND_CONTENT_EXISTS_ERROR);
|
|
367
|
+
const optionElements = getCompoundComponents(ComboboxOption, children);
|
|
368
|
+
const actionElements = getCompoundComponents(ComboboxAction, children);
|
|
369
|
+
const activatorElements = getCompoundComponents(ComboboxActivator, children);
|
|
370
|
+
const shouldThrowTriggerError = isInvalid(activatorElements);
|
|
371
|
+
useAssert.useAssert(shouldThrowTriggerError, COMBOBOX_TRIGGER_COUNT_ERROR_MESSAGE);
|
|
372
372
|
return {
|
|
373
|
-
contentElement,
|
|
374
|
-
triggerElement,
|
|
375
373
|
optionElements,
|
|
374
|
+
triggerElement: activatorElements[0],
|
|
376
375
|
actionElements,
|
|
377
376
|
};
|
|
378
377
|
}
|
|
379
|
-
function
|
|
380
|
-
return
|
|
381
|
-
(child.type === ComboboxTriggerButton ||
|
|
382
|
-
child.type === ComboboxTriggerChip ||
|
|
383
|
-
child.type === ComboboxActivator));
|
|
384
|
-
}
|
|
385
|
-
function isContentElement(child) {
|
|
386
|
-
return React__default["default"].isValidElement(child) && child.type === ComboboxContent;
|
|
378
|
+
function isInvalid(activators) {
|
|
379
|
+
return activators.length > 1 ? true : false;
|
|
387
380
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
function
|
|
392
|
-
|
|
381
|
+
/**
|
|
382
|
+
* Return all instances child component that matches the `type` provided
|
|
383
|
+
*/
|
|
384
|
+
function getCompoundComponents(type, children) {
|
|
385
|
+
const childrenArray = React.Children.toArray(children);
|
|
386
|
+
const elements = childrenArray.filter((child) => React.isValidElement(child) && child.type === type);
|
|
387
|
+
return elements;
|
|
393
388
|
}
|
|
394
389
|
|
|
395
|
-
function Combobox(
|
|
396
|
-
|
|
397
|
-
const
|
|
398
|
-
const buildOptions = optionElements.map(option => ({
|
|
390
|
+
function Combobox(props) {
|
|
391
|
+
const { optionElements, triggerElement, actionElements } = useComboboxValidation(props.children);
|
|
392
|
+
const options = React.useMemo(() => (optionElements === null || optionElements === void 0 ? void 0 : optionElements.map(option => ({
|
|
399
393
|
id: option.props.id,
|
|
400
394
|
label: option.props.label,
|
|
401
|
-
}));
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
395
|
+
}))) || [], [optionElements]);
|
|
396
|
+
const { selectedOptions, selectedStateSetter, shouldScroll, wrapperRef, searchValue, setSearchValue, open, setOpen, handleClose, handleSelection, } = useCombobox(props.selected, props.onSelect, props.onClose, props.multiSelect);
|
|
397
|
+
return (React__default["default"].createElement(ComboboxContextProvider, { selected: selectedOptions, selectionHandler: handleSelection, open: open, setOpen: setOpen, handleClose: handleClose, shouldScroll: shouldScroll },
|
|
398
|
+
React__default["default"].createElement("div", { ref: wrapperRef, className: styles.wrapper },
|
|
399
|
+
open && (React__default["default"].createElement("div", { className: styles.overlay, onClick: () => handleClose(), "data-testid": "ATL-Combobox-Overlay" })),
|
|
400
|
+
triggerElement || (React__default["default"].createElement(ComboboxTrigger, { label: props.label, selected: props.selected })),
|
|
401
|
+
React__default["default"].createElement(ComboboxContent, { multiselect: props.multiSelect, searchPlaceholder: props.searchPlaceholder, subjectNoun: props.subjectNoun, selected: selectedOptions, actionElements: actionElements, selectedStateSetter: selectedStateSetter, handleSelection: handleSelection, searchValue: searchValue, setSearchValue: setSearchValue, wrapperRef: wrapperRef, open: open, setOpen: setOpen, options: options }))));
|
|
407
402
|
}
|
|
408
|
-
/**
|
|
409
|
-
* @deprecated Use Combobox.Activator instead
|
|
410
|
-
*/
|
|
411
|
-
Combobox.TriggerButton = ComboboxTriggerButton;
|
|
412
|
-
/**
|
|
413
|
-
* @deprecated Use Combobox.Activator instead
|
|
414
|
-
*/
|
|
415
|
-
Combobox.TriggerChip = ComboboxTriggerChip;
|
|
416
403
|
Combobox.Activator = ComboboxActivator;
|
|
417
|
-
/**
|
|
418
|
-
* @deprecated Use individual Combobox.Option instead
|
|
419
|
-
*/
|
|
420
|
-
Combobox.Content = ComboboxContent;
|
|
421
404
|
Combobox.Action = ComboboxAction;
|
|
422
405
|
Combobox.Option = ComboboxOption;
|
|
423
406
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jobber/components",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.59.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -84,5 +84,5 @@
|
|
|
84
84
|
"> 1%",
|
|
85
85
|
"IE 10"
|
|
86
86
|
],
|
|
87
|
-
"gitHead": "
|
|
87
|
+
"gitHead": "6727b0e5428d011ebeec1f3b9bd642144964d977"
|
|
88
88
|
}
|