-
Notifications
You must be signed in to change notification settings - Fork 4k
/
index.tsx
131 lines (116 loc) · 3.12 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/**
* External dependencies
*/
// eslint-disable-next-line no-restricted-imports
import * as Ariakit from '@ariakit/react';
/**
* WordPress dependencies
*/
import { useMemo } from '@wordpress/element';
/**
* Internal dependencies
*/
import _CustomSelect from '../custom-select';
import CustomSelectItem from '../item';
import type { LegacyCustomSelectProps } from '../types';
import * as Styled from '../styles';
import { ContextSystemProvider } from '../../context';
function CustomSelectControl( props: LegacyCustomSelectProps ) {
const {
__experimentalShowSelectedHint,
__next40pxDefaultSize = false,
options,
onChange,
size = 'default',
value,
...restProps
} = props;
// Forward props + store from v2 implementation
const store = Ariakit.useSelectStore( {
async setValue( nextValue ) {
if ( ! onChange ) return;
// Executes the logic in a microtask after the popup is closed.
// This is simply to ensure the isOpen state matches that in Downshift.
await Promise.resolve();
const state = store.getState();
const changeObject = {
highlightedIndex: state.renderedItems.findIndex(
( item ) => item.value === nextValue
),
inputValue: '',
isOpen: state.open,
selectedItem: {
name: nextValue as string,
key: nextValue as string,
},
type: '',
};
onChange( changeObject );
},
} );
const children = options.map(
( { name, key, __experimentalHint, ...rest } ) => {
const withHint = (
<Styled.WithHintWrapper>
<span>{ name }</span>
<Styled.ExperimentalHintItem className="components-custom-select-control__item-hint">
{ __experimentalHint }
</Styled.ExperimentalHintItem>
</Styled.WithHintWrapper>
);
return (
<CustomSelectItem
key={ key }
value={ name }
children={ __experimentalHint ? withHint : name }
{ ...rest }
/>
);
}
);
const renderSelectedValueHint = () => {
const { value: currentValue } = store.getState();
const currentHint = options?.find(
( { name } ) => currentValue === name
);
return (
<>
{ currentValue }
<Styled.SelectedExperimentalHintItem className="components-custom-select-control__hint">
{ currentHint?.__experimentalHint }
</Styled.SelectedExperimentalHintItem>
</>
);
};
// translate legacy button sizing
const contextSystemValue = useMemo( () => {
let selectedSize;
if (
( __next40pxDefaultSize && size === 'default' ) ||
size === '__unstable-large'
) {
selectedSize = 'default';
} else if ( ! __next40pxDefaultSize && size === 'default' ) {
selectedSize = 'compact';
} else {
selectedSize = size;
}
return {
CustomSelectControlButton: { _overrides: { size: selectedSize } },
};
}, [ __next40pxDefaultSize, size ] );
const translatedProps = {
'aria-describedby': props.describedBy,
children,
renderSelectedValue: __experimentalShowSelectedHint
? renderSelectedValueHint
: undefined,
...restProps,
};
return (
<ContextSystemProvider value={ contextSystemValue }>
<_CustomSelect { ...translatedProps } store={ store } />
</ContextSystemProvider>
);
}
export default CustomSelectControl;