draft-components 3.2.1 → 3.3.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.
@@ -2056,6 +2056,168 @@
2056
2056
  color-scheme: dark;
2057
2057
  }
2058
2058
 
2059
+ .dc-search-select {
2060
+ --dc-search-select-font-size: 14px;
2061
+ --dc-search-select-text-color: var(--dc-control-primary-text-color);
2062
+ --dc-search-select-height: 36px;
2063
+ --dc-search-select-padding-x: 12px;
2064
+ --dc-search-select-radius: 7px;
2065
+ --dc-search-select-border-color: var(--dc-control-border-color);
2066
+ --dc-search-select-border-color-error: var(--dc-control-error-color);
2067
+ --dc-search-select-bg: var(--dc-control-bg);
2068
+ --dc-search-select-focus-ring-color: var(--dc-control-primary-color);
2069
+
2070
+ position: relative;
2071
+ box-sizing: border-box;
2072
+ display: inline-flex;
2073
+ align-items: center;
2074
+ max-width: 100%;
2075
+ height: var(--dc-search-select-height);
2076
+ padding: 0 var(--dc-search-select-padding-x);
2077
+ padding-right: calc(var(--dc-search-select-height) + 0.15em);
2078
+ font-family: var(--dc-primary-font);
2079
+ font-size: var(--dc-search-select-font-size);
2080
+ font-weight: 400;
2081
+ line-height: 1.25;
2082
+ color: var(--dc-search-select-text-color);
2083
+ vertical-align: middle;
2084
+ color-scheme: light;
2085
+ background: var(--dc-search-select-bg);
2086
+ border: 1px solid var(--dc-search-select-border-color);
2087
+ border-radius: var(--dc-search-select-radius);
2088
+ }
2089
+
2090
+ .dc-search-select:focus {
2091
+ border-color: var(--dc-search-select-focus-ring-color);
2092
+ box-shadow: 0 0 0 1px var(--dc-search-select-focus-ring-color);
2093
+ }
2094
+
2095
+ .dc-search-select_loading,
2096
+ .dc-search-select_disabled {
2097
+ pointer-events: none;
2098
+ }
2099
+
2100
+ .dc-search-select_disabled {
2101
+ opacity: var(--dc-disabled-state-opacity);
2102
+ }
2103
+
2104
+ .dc-search-select_invalid {
2105
+ border-color: var(--dc-search-select-border-color-error);
2106
+ }
2107
+
2108
+ .dc-search-select_full-width {
2109
+ display: flex;
2110
+ width: 100%;
2111
+ }
2112
+
2113
+ .dc-search-select_size_sm {
2114
+ --dc-search-select-font-size: 13px;
2115
+ --dc-search-select-height: 32px;
2116
+ --dc-search-select-padding-x: 8px;
2117
+ --dc-search-select-radius: 6px;
2118
+ }
2119
+
2120
+ .dc-search-select_size_lg {
2121
+ --dc-search-select-font-size: 15px;
2122
+ --dc-search-select-height: 40px;
2123
+ --dc-search-select-padding-x: 16px;
2124
+ --dc-search-select-radius: 8px;
2125
+ }
2126
+
2127
+ .dc-search-select__slot-left {
2128
+ position: absolute;
2129
+ top: 0;
2130
+ right: 0;
2131
+ display: inline-flex;
2132
+ flex-shrink: 0;
2133
+ align-items: center;
2134
+ justify-content: center;
2135
+ width: var(--dc-search-select-height);
2136
+ height: var(--dc-search-select-height);
2137
+ pointer-events: none;
2138
+ }
2139
+
2140
+ .dc-search-select__arrow {
2141
+ transform: translateY(5%);
2142
+ }
2143
+
2144
+ .dc-search-select__popover {
2145
+ padding: 0;
2146
+ padding-bottom: 8px;
2147
+ border-radius: 8px;
2148
+ }
2149
+
2150
+ .dc-search-select__textbox {
2151
+ padding: 8px;
2152
+ }
2153
+
2154
+ .dc-search-select__listbox {
2155
+ max-height: 352px;
2156
+ padding: 0 8px;
2157
+ margin: 0;
2158
+ overflow-y: auto;
2159
+ list-style: none;
2160
+ border-bottom-right-radius: inherit;
2161
+ border-bottom-left-radius: inherit;
2162
+ }
2163
+
2164
+ .dc-search-select__option {
2165
+ padding: 4px;
2166
+ font-size: 14px;
2167
+ color: inherit;
2168
+ cursor: default;
2169
+ border-radius: 4px;
2170
+ }
2171
+
2172
+ .dc-search-select__option_highlighted {
2173
+ color: var(--dc-control-primary-text-color);
2174
+ background: var(--dc-control-bg-inset);
2175
+ }
2176
+
2177
+ .dc-search-select__option_selected {
2178
+ color: var(--dc-control-on-primary-color);
2179
+ background: var(--dc-control-primary-color);
2180
+ }
2181
+
2182
+ .dc-search-select__listbox > .dc-search-select__option + .dc-search-select__option {
2183
+ margin-top: 2px;
2184
+ }
2185
+
2186
+ .dc-search-select__separator {
2187
+ display: flex;
2188
+ align-items: center;
2189
+ width: 100%;
2190
+ padding: 8px 0;
2191
+ }
2192
+
2193
+ .dc-search-select__separator::before,
2194
+ .dc-search-select__separator::after {
2195
+ display: block;
2196
+ height: 1px;
2197
+ content: '';
2198
+ background: var(--dc-control-bg-inset);
2199
+ }
2200
+
2201
+ .dc-search-select__separator::before {
2202
+ flex-shrink: 0;
2203
+ width: 12px;
2204
+ }
2205
+
2206
+ .dc-search-select__separator::after {
2207
+ flex-grow: 1;
2208
+ }
2209
+
2210
+ .dc-search-select__separator-label {
2211
+ padding: 0 8px;
2212
+ font-size: 12px;
2213
+ color: var(--dc-control-secondary-text-color);
2214
+ }
2215
+
2216
+ .dark .dc-search-select,
2217
+ .dark.dc-search-select {
2218
+ color-scheme: dark;
2219
+ }
2220
+
2059
2221
  .dc-switch {
2060
2222
  --dc-switch-width: 38px;
2061
2223
  --dc-switch-height: 24px;
@@ -24,6 +24,7 @@ export * from './popover/index.js';
24
24
  export * from './portal/index.js';
25
25
  export * from './positioner/index.js';
26
26
  export * from './radio/index.js';
27
+ export * from './search-select/index.js';
27
28
  export * from './segmented-control/index.js';
28
29
  export * from './select/index.js';
29
30
  export * from './selection-control/index.js';
@@ -24,6 +24,7 @@ export * from './popover/index.js';
24
24
  export * from './portal/index.js';
25
25
  export * from './positioner/index.js';
26
26
  export * from './radio/index.js';
27
+ export * from './search-select/index.js';
27
28
  export * from './segmented-control/index.js';
28
29
  export * from './select/index.js';
29
30
  export * from './selection-control/index.js';
@@ -0,0 +1,24 @@
1
+ import { ReactNode } from 'react';
2
+ export declare class OptionStore<T> {
3
+ private _map;
4
+ readonly idPrefix: string;
5
+ constructor(idPrefix?: string);
6
+ private _generateId;
7
+ get ids(): string[];
8
+ get values(): T[];
9
+ idOf(value: T): string | undefined;
10
+ append(value: T): string;
11
+ clear(): void;
12
+ }
13
+ export type SearchSelectContext<T> = {
14
+ options: OptionStore<T>;
15
+ selectedValue: T;
16
+ highlightedValue: T;
17
+ setSelectedValue: (value: T) => void;
18
+ setHighlightedValue: (value: T) => void;
19
+ };
20
+ export declare function useSearchSelectContext(): SearchSelectContext<any>;
21
+ export declare function SearchSelectContextProvider<T>({ value, children, }: {
22
+ value: SearchSelectContext<T>;
23
+ children: ReactNode;
24
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,47 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext } from 'react';
3
+ export class OptionStore {
4
+ _map;
5
+ idPrefix;
6
+ constructor(idPrefix = '') {
7
+ this._map = new Map();
8
+ this.idPrefix = idPrefix;
9
+ }
10
+ _generateId() {
11
+ const count = this._map.size;
12
+ return `${this.idPrefix}${count + 1}`;
13
+ }
14
+ get ids() {
15
+ return Array.from(this._map.values());
16
+ }
17
+ get values() {
18
+ return Array.from(this._map.keys());
19
+ }
20
+ idOf(value) {
21
+ return this._map.get(value);
22
+ }
23
+ append(value) {
24
+ let id = this._map.get(value);
25
+ if (id) {
26
+ return id;
27
+ }
28
+ id = this._generateId();
29
+ this._map.set(value, id);
30
+ return id;
31
+ }
32
+ clear() {
33
+ this._map.clear();
34
+ }
35
+ }
36
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
+ const searchSelectContext = createContext(null);
38
+ export function useSearchSelectContext() {
39
+ const ctx = useContext(searchSelectContext);
40
+ if (ctx === null) {
41
+ throw new Error('useSearchSelectContext must be used within SearchSelectContextProvider');
42
+ }
43
+ return ctx;
44
+ }
45
+ export function SearchSelectContextProvider({ value, children, }) {
46
+ return (_jsx(searchSelectContext.Provider, { value: value, children: children }));
47
+ }
@@ -0,0 +1,3 @@
1
+ import { ComponentPropsWithoutRef } from 'react';
2
+ export declare function MagnifyingGlass({ width, height, ...props }: ComponentPropsWithoutRef<'svg'>): import("react/jsx-runtime").JSX.Element;
3
+ export declare function ChevronDown({ width, height, ...props }: ComponentPropsWithoutRef<'svg'>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ export function MagnifyingGlass({ width = 24, height = 24, ...props }) {
3
+ return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", width: width, height: height, strokeWidth: 1.5, stroke: "currentColor", ...props, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z" }) }));
4
+ }
5
+ export function ChevronDown({ width = 24, height = 24, ...props }) {
6
+ return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", width: width, height: height, strokeWidth: 1.5, stroke: "currentColor", ...props, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "m19.5 8.25-7.5 7.5-7.5-7.5" }) }));
7
+ }
@@ -0,0 +1 @@
1
+ export * from './search-select.js';
@@ -0,0 +1 @@
1
+ export * from './search-select.js';
@@ -0,0 +1,161 @@
1
+ .dc-search-select {
2
+ --dc-search-select-font-size: 14px;
3
+ --dc-search-select-text-color: var(--dc-control-primary-text-color);
4
+ --dc-search-select-height: 36px;
5
+ --dc-search-select-padding-x: 12px;
6
+ --dc-search-select-radius: 7px;
7
+ --dc-search-select-border-color: var(--dc-control-border-color);
8
+ --dc-search-select-border-color-error: var(--dc-control-error-color);
9
+ --dc-search-select-bg: var(--dc-control-bg);
10
+ --dc-search-select-focus-ring-color: var(--dc-control-primary-color);
11
+
12
+ position: relative;
13
+ box-sizing: border-box;
14
+ display: inline-flex;
15
+ align-items: center;
16
+ max-width: 100%;
17
+ height: var(--dc-search-select-height);
18
+ padding: 0 var(--dc-search-select-padding-x);
19
+ padding-right: calc(var(--dc-search-select-height) + 0.15em);
20
+ font-family: var(--dc-primary-font);
21
+ font-size: var(--dc-search-select-font-size);
22
+ font-weight: 400;
23
+ line-height: 1.25;
24
+ color: var(--dc-search-select-text-color);
25
+ vertical-align: middle;
26
+ color-scheme: light;
27
+ background: var(--dc-search-select-bg);
28
+ border: 1px solid var(--dc-search-select-border-color);
29
+ border-radius: var(--dc-search-select-radius);
30
+ }
31
+
32
+ .dc-search-select:focus {
33
+ border-color: var(--dc-search-select-focus-ring-color);
34
+ box-shadow: 0 0 0 1px var(--dc-search-select-focus-ring-color);
35
+ }
36
+
37
+ .dc-search-select_loading,
38
+ .dc-search-select_disabled {
39
+ pointer-events: none;
40
+ }
41
+
42
+ .dc-search-select_disabled {
43
+ opacity: var(--dc-disabled-state-opacity);
44
+ }
45
+
46
+ .dc-search-select_invalid {
47
+ border-color: var(--dc-search-select-border-color-error);
48
+ }
49
+
50
+ .dc-search-select_full-width {
51
+ display: flex;
52
+ width: 100%;
53
+ }
54
+
55
+ .dc-search-select_size_sm {
56
+ --dc-search-select-font-size: 13px;
57
+ --dc-search-select-height: 32px;
58
+ --dc-search-select-padding-x: 8px;
59
+ --dc-search-select-radius: 6px;
60
+ }
61
+
62
+ .dc-search-select_size_lg {
63
+ --dc-search-select-font-size: 15px;
64
+ --dc-search-select-height: 40px;
65
+ --dc-search-select-padding-x: 16px;
66
+ --dc-search-select-radius: 8px;
67
+ }
68
+
69
+ .dc-search-select__slot-left {
70
+ position: absolute;
71
+ top: 0;
72
+ right: 0;
73
+ display: inline-flex;
74
+ flex-shrink: 0;
75
+ align-items: center;
76
+ justify-content: center;
77
+ width: var(--dc-search-select-height);
78
+ height: var(--dc-search-select-height);
79
+ pointer-events: none;
80
+ }
81
+
82
+ .dc-search-select__arrow {
83
+ transform: translateY(5%);
84
+ }
85
+
86
+ .dc-search-select__popover {
87
+ padding: 0;
88
+ padding-bottom: 8px;
89
+ border-radius: 8px;
90
+ }
91
+
92
+ .dc-search-select__textbox {
93
+ padding: 8px;
94
+ }
95
+
96
+ .dc-search-select__listbox {
97
+ max-height: 352px;
98
+ padding: 0 8px;
99
+ margin: 0;
100
+ overflow-y: auto;
101
+ list-style: none;
102
+ border-bottom-right-radius: inherit;
103
+ border-bottom-left-radius: inherit;
104
+ }
105
+
106
+ .dc-search-select__option {
107
+ padding: 4px;
108
+ font-size: 14px;
109
+ color: inherit;
110
+ cursor: default;
111
+ border-radius: 4px;
112
+ }
113
+
114
+ .dc-search-select__option_highlighted {
115
+ color: var(--dc-control-primary-text-color);
116
+ background: var(--dc-control-bg-inset);
117
+ }
118
+
119
+ .dc-search-select__option_selected {
120
+ color: var(--dc-control-on-primary-color);
121
+ background: var(--dc-control-primary-color);
122
+ }
123
+
124
+ .dc-search-select__listbox > .dc-search-select__option + .dc-search-select__option {
125
+ margin-top: 2px;
126
+ }
127
+
128
+ .dc-search-select__separator {
129
+ display: flex;
130
+ align-items: center;
131
+ width: 100%;
132
+ padding: 8px 0;
133
+ }
134
+
135
+ .dc-search-select__separator::before,
136
+ .dc-search-select__separator::after {
137
+ display: block;
138
+ height: 1px;
139
+ content: '';
140
+ background: var(--dc-control-bg-inset);
141
+ }
142
+
143
+ .dc-search-select__separator::before {
144
+ flex-shrink: 0;
145
+ width: 12px;
146
+ }
147
+
148
+ .dc-search-select__separator::after {
149
+ flex-grow: 1;
150
+ }
151
+
152
+ .dc-search-select__separator-label {
153
+ padding: 0 8px;
154
+ font-size: 12px;
155
+ color: var(--dc-control-secondary-text-color);
156
+ }
157
+
158
+ .dark .dc-search-select,
159
+ .dark.dc-search-select {
160
+ color-scheme: dark;
161
+ }
@@ -0,0 +1,36 @@
1
+ import { ReactNode } from 'react';
2
+ type RenderLabelFn<Value> = (value: Value) => ReactNode;
3
+ type RenderOptionsFn = (props: {
4
+ searchQuery: string;
5
+ searchQueryLowercased: string;
6
+ }) => ReactNode;
7
+ export type SearchSelectSize = 'sm' | 'md' | 'lg';
8
+ export type SearchSelectProps<Value> = {
9
+ className?: string;
10
+ size?: SearchSelectSize;
11
+ fullWidth?: boolean;
12
+ invalid?: boolean;
13
+ loading?: boolean;
14
+ disabled?: boolean;
15
+ textboxIcon?: ReactNode;
16
+ textboxAriaLabel?: string;
17
+ textboxPlaceholder?: string;
18
+ labelledBy?: string;
19
+ displayedValue?: ReactNode | RenderLabelFn<Value>;
20
+ children?: ReactNode | RenderOptionsFn;
21
+ value: Value;
22
+ onChange: (value: Value) => void;
23
+ };
24
+ export declare function SearchSelect<Value>({ className, size, fullWidth, invalid, loading, disabled, textboxIcon, textboxAriaLabel, textboxPlaceholder, labelledBy, displayedValue, children, value: selectedValue, onChange: onSelectedValueChange, }: SearchSelectProps<Value>): import("react/jsx-runtime").JSX.Element;
25
+ export declare namespace SearchSelect {
26
+ var Option: <T>({ className, value, children, }: {
27
+ className?: string | undefined;
28
+ value: T;
29
+ children: ReactNode;
30
+ }) => import("react/jsx-runtime").JSX.Element;
31
+ var Separator: ({ className, children, }: {
32
+ className?: string | undefined;
33
+ children?: ReactNode;
34
+ }) => import("react/jsx-runtime").JSX.Element;
35
+ }
36
+ export {};
@@ -0,0 +1,175 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useId, useState, useEffect, } from 'react';
3
+ import { useSearchSelectContext, SearchSelectContextProvider, OptionStore, } from './context.js';
4
+ import { classNames } from '../../lib/react-helpers.js';
5
+ import { Popover } from '../popover/popover.js';
6
+ import { TextInput } from '../text-input/text-input.js';
7
+ import { Spinner } from '../spinner/spinner.js';
8
+ import { ChevronDown, MagnifyingGlass } from './icons.js';
9
+ export function SearchSelect({ className, size = 'md', fullWidth, invalid, loading, disabled, textboxIcon, textboxAriaLabel, textboxPlaceholder = '', labelledBy, displayedValue, children, value: selectedValue, onChange: onSelectedValueChange, }) {
10
+ const id = useId();
11
+ const buttonId = `${id}button`;
12
+ const textboxId = `${id}textbox`;
13
+ const listboxId = `${id}listbox`;
14
+ const [options] = useState(() => new OptionStore(`${id}option-`));
15
+ const [isOpen, setIsOpen] = useState(false);
16
+ const [searchQuery, setSearchQuery] = useState('');
17
+ const [highlightedValue, setHighlightedValue] = useState(selectedValue);
18
+ const openPopover = () => {
19
+ if (disabled || loading) {
20
+ return;
21
+ }
22
+ options.clear();
23
+ setSearchQuery('');
24
+ setHighlightedValue(selectedValue);
25
+ setIsOpen(true);
26
+ window.setTimeout(() => {
27
+ const textbox = window.document.getElementById(textboxId);
28
+ if (textbox) {
29
+ textbox.focus();
30
+ }
31
+ });
32
+ };
33
+ const closePopover = () => {
34
+ setIsOpen(false);
35
+ window.setTimeout(() => {
36
+ const button = window.document.getElementById(buttonId);
37
+ if (button) {
38
+ button.focus();
39
+ }
40
+ });
41
+ };
42
+ const setSelectedValue = (value) => {
43
+ onSelectedValueChange(value);
44
+ closePopover();
45
+ };
46
+ const handleButtonClick = () => {
47
+ if (isOpen) {
48
+ closePopover();
49
+ }
50
+ else {
51
+ openPopover();
52
+ }
53
+ };
54
+ const handleButtonKeyDown = (event) => {
55
+ let handled = false;
56
+ if (event.key === 'ArrowUp') {
57
+ handled = true;
58
+ openPopover();
59
+ }
60
+ else if (event.key === 'ArrowDown') {
61
+ handled = true;
62
+ openPopover();
63
+ }
64
+ if (handled) {
65
+ event.preventDefault();
66
+ event.stopPropagation();
67
+ }
68
+ };
69
+ const handleTextboxChange = (event) => {
70
+ options.clear();
71
+ setSearchQuery(event.target.value);
72
+ };
73
+ const handleTextboxKeyDown = (event) => {
74
+ let handled = false;
75
+ if (event.key === 'ArrowUp') {
76
+ handled = true;
77
+ const values = options.values;
78
+ const index = values.indexOf(highlightedValue) - 1;
79
+ setHighlightedValue(index >= 0
80
+ ? values[index]
81
+ : values[values.length - 1]);
82
+ }
83
+ if (event.key === 'ArrowDown') {
84
+ handled = true;
85
+ const values = options.values;
86
+ const index = values.indexOf(highlightedValue) + 1;
87
+ setHighlightedValue(index < values.length
88
+ ? values[index]
89
+ : values[0]);
90
+ }
91
+ if (event.key === 'Home') {
92
+ handled = true;
93
+ const values = options.values;
94
+ setHighlightedValue(values[0]);
95
+ }
96
+ if (event.key === 'End') {
97
+ handled = true;
98
+ const values = options.values;
99
+ setHighlightedValue(values[values.length - 1]);
100
+ }
101
+ if (event.key === 'Enter') {
102
+ handled = true;
103
+ setSelectedValue(highlightedValue);
104
+ }
105
+ if (handled) {
106
+ event.preventDefault();
107
+ event.stopPropagation();
108
+ }
109
+ };
110
+ useEffect(() => {
111
+ const optionId = options.idOf(highlightedValue);
112
+ if (!optionId) {
113
+ return;
114
+ }
115
+ const listbox = window.document.getElementById(listboxId);
116
+ const option = window.document.getElementById(optionId);
117
+ if (!listbox || !option) {
118
+ return;
119
+ }
120
+ const listboxRect = listbox.getBoundingClientRect();
121
+ const optionRect = option.getBoundingClientRect();
122
+ if (optionRect.top < listboxRect.top) {
123
+ listbox.scrollTo({
124
+ top: optionRect.top - listboxRect.top + listbox.scrollTop,
125
+ });
126
+ }
127
+ else if (optionRect.bottom > listboxRect.bottom) {
128
+ listbox.scrollTo({
129
+ top: optionRect.bottom - listboxRect.bottom + listbox.scrollTop,
130
+ });
131
+ }
132
+ }, [listboxId, options, highlightedValue]);
133
+ const ctx = {
134
+ options: options,
135
+ selectedValue,
136
+ highlightedValue,
137
+ setSelectedValue: setSelectedValue,
138
+ setHighlightedValue: setHighlightedValue,
139
+ };
140
+ return (_jsx(Popover, { className: "dc-search-select__popover", isOpen: isOpen, onClose: closePopover, anchor: (_jsxs("button", { className: classNames(className, {
141
+ 'dc-search-select': true,
142
+ 'dc-search-select_full-width': fullWidth,
143
+ 'dc-search-select_invalid': invalid,
144
+ 'dc-search-select_loading': loading,
145
+ 'dc-search-select_disabled': disabled,
146
+ [`dc-search-select_size_${size}`]: size,
147
+ }), id: buttonId, "aria-expanded": isOpen, "aria-controls": listboxId, "aria-labelledby": labelledBy, tabIndex: disabled || loading ? -1 : undefined, type: "button", onClick: handleButtonClick, onKeyDown: handleButtonKeyDown, children: [typeof displayedValue === 'function'
148
+ ? displayedValue(selectedValue)
149
+ : displayedValue, _jsx("span", { className: "dc-search-select__slot-left", children: loading
150
+ ? (_jsx(Spinner, { className: "dc-search-select__spinner", width: "1.05em", height: "1.05em" }))
151
+ : (_jsx(ChevronDown, { className: "dc-search-select__arrow", width: "1.05em", height: "1.05em", strokeWidth: 2 })) })] })), alignment: "start", placement: "bottom", children: _jsxs(_Fragment, { children: [_jsx("div", { className: "dc-search-select__textbox", children: _jsx(TextInput, { id: textboxId, fullWidth: true, slotLeft: textboxIcon || _jsx(MagnifyingGlass, { width: 16, height: 16 }), placeholder: textboxPlaceholder, size: "sm", type: "text", role: "combobox", "aria-controls": listboxId, "aria-expanded": "true", "aria-autocomplete": "list", "aria-activedescendant": options.idOf(highlightedValue), "aria-label": textboxAriaLabel, value: searchQuery, onChange: handleTextboxChange, onKeyDown: handleTextboxKeyDown }) }), _jsx(SearchSelectContextProvider, { value: ctx, children: _jsx("ul", { className: "dc-search-select__listbox", id: listboxId, role: "listbox", children: typeof children === 'function'
152
+ ? children({
153
+ searchQuery,
154
+ searchQueryLowercased: searchQuery.toLowerCase(),
155
+ })
156
+ : children }) })] }) }));
157
+ }
158
+ SearchSelect.Option = function SearchSelectOption({ className, value, children, }) {
159
+ const { options, selectedValue, highlightedValue, setSelectedValue, setHighlightedValue, } = useSearchSelectContext();
160
+ const id = options.append(value);
161
+ const selected = value === selectedValue;
162
+ const highlighted = value === highlightedValue;
163
+ return (
164
+ /* eslint-disable jsx-a11y/click-events-have-key-events */
165
+ _jsx("li", { className: classNames(className, {
166
+ 'dc-search-select__option': true,
167
+ 'dc-search-select__option_selected': selected,
168
+ 'dc-search-select__option_highlighted': highlighted,
169
+ }), id: id, role: "option", "aria-selected": highlighted, onClick: () => setSelectedValue(value), onMouseEnter: () => setHighlightedValue(value), children: children }));
170
+ };
171
+ SearchSelect.Separator = function SearchSelectSeparator({ className, children, }) {
172
+ return (_jsx("li", { className: classNames('dc-search-select__separator', className), role: "separator", children: children
173
+ ? _jsx("div", { className: "dc-search-select__separator-label", children: children })
174
+ : null }));
175
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "draft-components",
3
- "version": "3.2.1",
3
+ "version": "3.3.0",
4
4
  "description": "The React based UI components library.",
5
5
  "type": "module",
6
6
  "exports": {