@elementor/editor-controls 4.2.0-839 → 4.2.0-841
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/index.d.mts +11 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +1215 -1095
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +877 -758
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -15
- package/src/components/chips-list.tsx +22 -0
- package/src/controls/chips-control.tsx +9 -7
- package/src/controls/query-chips-control.tsx +110 -0
- package/src/controls/query-control.tsx +9 -81
- package/src/hooks/use-query-autocomplete.ts +118 -0
- package/src/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-controls",
|
|
3
3
|
"description": "This package contains the controls model and utils for the Elementor editor",
|
|
4
|
-
"version": "4.2.0-
|
|
4
|
+
"version": "4.2.0-841",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -40,22 +40,22 @@
|
|
|
40
40
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@elementor/editor-current-user": "4.2.0-
|
|
44
|
-
"@elementor/editor-elements": "4.2.0-
|
|
45
|
-
"@elementor/editor-props": "4.2.0-
|
|
46
|
-
"@elementor/editor-responsive": "4.2.0-
|
|
47
|
-
"@elementor/editor-ui": "4.2.0-
|
|
48
|
-
"@elementor/editor-v1-adapters": "4.2.0-
|
|
49
|
-
"@elementor/env": "4.2.0-
|
|
50
|
-
"@elementor/events": "4.2.0-
|
|
51
|
-
"@elementor/http-client": "4.2.0-
|
|
43
|
+
"@elementor/editor-current-user": "4.2.0-841",
|
|
44
|
+
"@elementor/editor-elements": "4.2.0-841",
|
|
45
|
+
"@elementor/editor-props": "4.2.0-841",
|
|
46
|
+
"@elementor/editor-responsive": "4.2.0-841",
|
|
47
|
+
"@elementor/editor-ui": "4.2.0-841",
|
|
48
|
+
"@elementor/editor-v1-adapters": "4.2.0-841",
|
|
49
|
+
"@elementor/env": "4.2.0-841",
|
|
50
|
+
"@elementor/events": "4.2.0-841",
|
|
51
|
+
"@elementor/http-client": "4.2.0-841",
|
|
52
52
|
"@elementor/icons": "~1.75.1",
|
|
53
|
-
"@elementor/locations": "4.2.0-
|
|
54
|
-
"@elementor/query": "4.2.0-
|
|
55
|
-
"@elementor/session": "4.2.0-
|
|
53
|
+
"@elementor/locations": "4.2.0-841",
|
|
54
|
+
"@elementor/query": "4.2.0-841",
|
|
55
|
+
"@elementor/session": "4.2.0-841",
|
|
56
56
|
"@elementor/ui": "1.37.5",
|
|
57
|
-
"@elementor/utils": "4.2.0-
|
|
58
|
-
"@elementor/wp-media": "4.2.0-
|
|
57
|
+
"@elementor/utils": "4.2.0-841",
|
|
58
|
+
"@elementor/wp-media": "4.2.0-841",
|
|
59
59
|
"@monaco-editor/react": "^4.7.0",
|
|
60
60
|
"@tiptap/extension-bold": "^3.11.1",
|
|
61
61
|
"@tiptap/extension-document": "^3.11.1",
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type AutocompleteRenderGetTagProps, Chip } from '@elementor/ui';
|
|
3
|
+
|
|
4
|
+
const CHIP_SIZE = 'tiny' as const;
|
|
5
|
+
|
|
6
|
+
export type ChipsListProps< Option > = {
|
|
7
|
+
getLabel: ( option: Option ) => string;
|
|
8
|
+
getTagProps: AutocompleteRenderGetTagProps;
|
|
9
|
+
values: Option[];
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function ChipsList< Option >( { getLabel, getTagProps, values }: ChipsListProps< Option > ) {
|
|
13
|
+
return (
|
|
14
|
+
<>
|
|
15
|
+
{ values.map( ( option, index ) => {
|
|
16
|
+
const { key, ...tagProps } = getTagProps( { index } );
|
|
17
|
+
|
|
18
|
+
return <Chip key={ key } label={ getLabel( option ) } size={ CHIP_SIZE } { ...tagProps } />;
|
|
19
|
+
} ) }
|
|
20
|
+
</>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { type SyntheticEvent } from 'react';
|
|
3
3
|
import { stringArrayPropTypeUtil, stringPropTypeUtil } from '@elementor/editor-props';
|
|
4
|
-
import { Autocomplete,
|
|
4
|
+
import { Autocomplete, TextField } from '@elementor/ui';
|
|
5
5
|
|
|
6
6
|
import { useBoundProp } from '../bound-prop-context';
|
|
7
|
+
import { ChipsList } from '../components/chips-list';
|
|
7
8
|
import ControlActions from '../control-actions/control-actions';
|
|
8
9
|
import { createControl } from '../create-control';
|
|
9
10
|
|
|
@@ -47,12 +48,13 @@ export const ChipsControl = createControl( ( { options }: ChipsControlProps ) =>
|
|
|
47
48
|
getOptionLabel={ ( option ) => option.label }
|
|
48
49
|
isOptionEqualToValue={ ( option, val ) => option.value === val.value }
|
|
49
50
|
renderInput={ ( params ) => <TextField { ...params } /> }
|
|
50
|
-
renderTags={ (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
renderTags={ ( tagValues, getTagProps ) => (
|
|
52
|
+
<ChipsList
|
|
53
|
+
getLabel={ ( option ) => option.label }
|
|
54
|
+
getTagProps={ getTagProps }
|
|
55
|
+
values={ tagValues }
|
|
56
|
+
/>
|
|
57
|
+
) }
|
|
56
58
|
/>
|
|
57
59
|
</ControlActions>
|
|
58
60
|
);
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type SyntheticEvent, useMemo } from 'react';
|
|
3
|
+
import {
|
|
4
|
+
createArrayPropUtils,
|
|
5
|
+
numberPropTypeUtil,
|
|
6
|
+
queryPropTypeUtil,
|
|
7
|
+
type QueryPropValue,
|
|
8
|
+
stringPropTypeUtil,
|
|
9
|
+
} from '@elementor/editor-props';
|
|
10
|
+
import { Autocomplete, TextField } from '@elementor/ui';
|
|
11
|
+
import { __ } from '@wordpress/i18n';
|
|
12
|
+
|
|
13
|
+
import { useBoundProp } from '../bound-prop-context';
|
|
14
|
+
import { ChipsList } from '../components/chips-list';
|
|
15
|
+
import ControlActions from '../control-actions/control-actions';
|
|
16
|
+
import { createControl } from '../create-control';
|
|
17
|
+
import { extractFlatOptionFromQueryValue, useQueryAutocomplete } from '../hooks/use-query-autocomplete';
|
|
18
|
+
|
|
19
|
+
type QueryChipsControlProps = {
|
|
20
|
+
queryOptions: {
|
|
21
|
+
params: Record< string, unknown >;
|
|
22
|
+
url: string;
|
|
23
|
+
};
|
|
24
|
+
placeholder?: string;
|
|
25
|
+
minInputLength?: number;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
type ChipOption = {
|
|
29
|
+
id: string;
|
|
30
|
+
label: string;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const queryArrayPropTypeUtil = createArrayPropUtils( queryPropTypeUtil.key, queryPropTypeUtil.schema );
|
|
34
|
+
|
|
35
|
+
const SIZE = 'tiny';
|
|
36
|
+
|
|
37
|
+
export const QueryChipsControl = createControl( ( props: QueryChipsControlProps ) => {
|
|
38
|
+
const { queryOptions, placeholder, minInputLength = 2 } = props;
|
|
39
|
+
const { value, setValue, disabled } = useBoundProp( queryArrayPropTypeUtil );
|
|
40
|
+
|
|
41
|
+
const selectedChips = useMemo< ChipOption[] >( () => extractChips( value ), [ value ] );
|
|
42
|
+
|
|
43
|
+
const excludeIds = useMemo(
|
|
44
|
+
() =>
|
|
45
|
+
selectedChips.map( ( chip ) => Number( chip.id ) ).filter( ( id ): id is number => Number.isFinite( id ) ),
|
|
46
|
+
[ selectedChips ]
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const { options, updateOptions } = useQueryAutocomplete( {
|
|
50
|
+
url: queryOptions.url,
|
|
51
|
+
params: queryOptions.params,
|
|
52
|
+
minInputLength,
|
|
53
|
+
excludeIds,
|
|
54
|
+
} );
|
|
55
|
+
|
|
56
|
+
const handleChange = ( _: SyntheticEvent, newValue: ChipOption[] ) => {
|
|
57
|
+
setValue(
|
|
58
|
+
newValue.map( ( option ) =>
|
|
59
|
+
queryPropTypeUtil.create( {
|
|
60
|
+
id: numberPropTypeUtil.create( Number( option.id ) ),
|
|
61
|
+
label: stringPropTypeUtil.create( option.label ),
|
|
62
|
+
} )
|
|
63
|
+
)
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const handleInputChange = ( _: SyntheticEvent, term: string ) => {
|
|
68
|
+
updateOptions( term || null );
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<ControlActions>
|
|
73
|
+
<Autocomplete
|
|
74
|
+
multiple
|
|
75
|
+
fullWidth
|
|
76
|
+
disableClearable
|
|
77
|
+
forcePopupIcon={ false }
|
|
78
|
+
disabled={ disabled }
|
|
79
|
+
size={ SIZE }
|
|
80
|
+
value={ selectedChips }
|
|
81
|
+
options={ options as ChipOption[] }
|
|
82
|
+
onChange={ handleChange }
|
|
83
|
+
onInputChange={ handleInputChange }
|
|
84
|
+
getOptionLabel={ ( option ) => option.label }
|
|
85
|
+
isOptionEqualToValue={ ( option, val ) => option.id === val.id }
|
|
86
|
+
filterOptions={ ( opts ) => opts }
|
|
87
|
+
renderTags={ ( tagValues, getTagProps ) => (
|
|
88
|
+
<ChipsList
|
|
89
|
+
getLabel={ ( option ) => option.label }
|
|
90
|
+
getTagProps={ getTagProps }
|
|
91
|
+
values={ tagValues }
|
|
92
|
+
/>
|
|
93
|
+
) }
|
|
94
|
+
renderInput={ ( params ) => (
|
|
95
|
+
<TextField { ...params } placeholder={ placeholder ?? __( 'Search', 'elementor' ) } />
|
|
96
|
+
) }
|
|
97
|
+
/>
|
|
98
|
+
</ControlActions>
|
|
99
|
+
);
|
|
100
|
+
} );
|
|
101
|
+
|
|
102
|
+
function extractChips( value: QueryPropValue[] | null | undefined ): ChipOption[] {
|
|
103
|
+
if ( ! value ) {
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return value
|
|
108
|
+
.map( ( item ) => extractFlatOptionFromQueryValue( item?.value ) )
|
|
109
|
+
.filter( ( chip ): chip is ChipOption => chip !== null );
|
|
110
|
+
}
|
|
@@ -1,27 +1,13 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
numberPropTypeUtil,
|
|
5
|
-
queryPropTypeUtil,
|
|
6
|
-
type QueryPropValue,
|
|
7
|
-
stringPropTypeUtil,
|
|
8
|
-
urlPropTypeUtil,
|
|
9
|
-
} from '@elementor/editor-props';
|
|
10
|
-
import { type HttpResponse, httpService } from '@elementor/http-client';
|
|
2
|
+
import { numberPropTypeUtil, queryPropTypeUtil, stringPropTypeUtil, urlPropTypeUtil } from '@elementor/editor-props';
|
|
11
3
|
import { SearchIcon } from '@elementor/icons';
|
|
12
|
-
import { debounce } from '@elementor/utils';
|
|
13
4
|
import { __ } from '@wordpress/i18n';
|
|
14
5
|
|
|
15
6
|
import { useBoundProp } from '../bound-prop-context';
|
|
16
|
-
import {
|
|
17
|
-
Autocomplete,
|
|
18
|
-
type CategorizedOption,
|
|
19
|
-
findMatchingOption,
|
|
20
|
-
type FlatOption,
|
|
21
|
-
isCategorizedOptionPool,
|
|
22
|
-
} from '../components/autocomplete';
|
|
7
|
+
import { Autocomplete, findMatchingOption } from '../components/autocomplete';
|
|
23
8
|
import ControlActions from '../control-actions/control-actions';
|
|
24
9
|
import { createControl } from '../create-control';
|
|
10
|
+
import { useQueryAutocomplete } from '../hooks/use-query-autocomplete';
|
|
25
11
|
import { type DestinationProp } from './link-control';
|
|
26
12
|
|
|
27
13
|
type Props = {
|
|
@@ -36,10 +22,6 @@ type Props = {
|
|
|
36
22
|
ariaLabel?: string;
|
|
37
23
|
};
|
|
38
24
|
|
|
39
|
-
type Response = HttpResponse< { value: FlatOption[] | CategorizedOption[] } >;
|
|
40
|
-
|
|
41
|
-
type FetchOptionsParams = Record< string, unknown > & { term: string };
|
|
42
|
-
|
|
43
25
|
export const QueryControl = createControl( ( props: Props ) => {
|
|
44
26
|
const { value: queryValue, setValue: setQueryValue } = useBoundProp( queryPropTypeUtil );
|
|
45
27
|
const { value: urlValue, setValue: setUrlValue, placeholder: urlPlaceholder } = useBoundProp( urlPropTypeUtil );
|
|
@@ -53,9 +35,12 @@ export const QueryControl = createControl( ( props: Props ) => {
|
|
|
53
35
|
ariaLabel,
|
|
54
36
|
} = props || {};
|
|
55
37
|
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
38
|
+
const { options, updateOptions } = useQueryAutocomplete( {
|
|
39
|
+
url,
|
|
40
|
+
params,
|
|
41
|
+
minInputLength,
|
|
42
|
+
initialQueryValue: queryValue,
|
|
43
|
+
} );
|
|
59
44
|
|
|
60
45
|
const onOptionChange = ( newValue: number | null ) => {
|
|
61
46
|
if ( newValue === null ) {
|
|
@@ -89,28 +74,6 @@ export const QueryControl = createControl( ( props: Props ) => {
|
|
|
89
74
|
updateOptions( newValue );
|
|
90
75
|
};
|
|
91
76
|
|
|
92
|
-
const updateOptions = ( newValue: string | null ) => {
|
|
93
|
-
setOptions( [] );
|
|
94
|
-
|
|
95
|
-
if ( ! newValue || ! url || newValue.length < minInputLength ) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
debounceFetch( { ...params, term: newValue } );
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
const debounceFetch = useMemo(
|
|
103
|
-
() =>
|
|
104
|
-
debounce(
|
|
105
|
-
( queryParams: FetchOptionsParams ) =>
|
|
106
|
-
fetchOptions( url, queryParams ).then( ( newOptions ) => {
|
|
107
|
-
setOptions( formatOptions( newOptions ) );
|
|
108
|
-
} ),
|
|
109
|
-
400
|
|
110
|
-
),
|
|
111
|
-
[ url ]
|
|
112
|
-
);
|
|
113
|
-
|
|
114
77
|
const displayValue = queryValue?.id?.value ?? urlValue;
|
|
115
78
|
|
|
116
79
|
return (
|
|
@@ -132,38 +95,3 @@ export const QueryControl = createControl( ( props: Props ) => {
|
|
|
132
95
|
</ControlActions>
|
|
133
96
|
);
|
|
134
97
|
} );
|
|
135
|
-
|
|
136
|
-
async function fetchOptions( ajaxUrl: string, params: FetchOptionsParams ) {
|
|
137
|
-
if ( ! params || ! ajaxUrl ) {
|
|
138
|
-
return [];
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
try {
|
|
142
|
-
const { data: response } = await httpService().get< Response >( ajaxUrl, { params } );
|
|
143
|
-
|
|
144
|
-
return response.data.value;
|
|
145
|
-
} catch {
|
|
146
|
-
return [];
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
function formatOptions( options: FlatOption[] | CategorizedOption[] ): FlatOption[] | CategorizedOption[] {
|
|
151
|
-
const compareKey = isCategorizedOptionPool( options ) ? 'groupLabel' : 'label';
|
|
152
|
-
|
|
153
|
-
return options.sort( ( a, b ) =>
|
|
154
|
-
a[ compareKey ] && b[ compareKey ] ? a[ compareKey ].localeCompare( b[ compareKey ] ) : 0
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function generateFirstLoadedOption( queryValue: QueryPropValue[ 'value' ] | null ): FlatOption[] {
|
|
159
|
-
const id = queryValue?.id?.value;
|
|
160
|
-
const label = queryValue?.label?.value;
|
|
161
|
-
|
|
162
|
-
const option = [];
|
|
163
|
-
|
|
164
|
-
if ( id && label ) {
|
|
165
|
-
option.push( { id: id.toString(), label } );
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
return option;
|
|
169
|
-
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { useMemo, useState } from 'react';
|
|
2
|
+
import { numberPropTypeUtil, type QueryPropValue, stringPropTypeUtil } from '@elementor/editor-props';
|
|
3
|
+
import { type HttpResponse, httpService } from '@elementor/http-client';
|
|
4
|
+
import { debounce } from '@elementor/utils';
|
|
5
|
+
|
|
6
|
+
import { type CategorizedOption, type FlatOption, isCategorizedOptionPool } from '../components/autocomplete';
|
|
7
|
+
|
|
8
|
+
type Response = HttpResponse< { value: FlatOption[] | CategorizedOption[] } >;
|
|
9
|
+
|
|
10
|
+
type FetchOptionsParams = Record< string, unknown > & { term: string };
|
|
11
|
+
|
|
12
|
+
type UseQueryAutocompleteOptions = {
|
|
13
|
+
url: string;
|
|
14
|
+
params?: Record< string, unknown >;
|
|
15
|
+
minInputLength?: number;
|
|
16
|
+
initialQueryValue?: QueryPropValue[ 'value' ] | null;
|
|
17
|
+
excludeIds?: number[];
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type UseQueryAutocompleteResult = {
|
|
21
|
+
options: FlatOption[] | CategorizedOption[];
|
|
22
|
+
updateOptions: ( term: string | null ) => void;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export function useQueryAutocomplete( {
|
|
26
|
+
url,
|
|
27
|
+
params = {},
|
|
28
|
+
minInputLength = 2,
|
|
29
|
+
initialQueryValue = null,
|
|
30
|
+
excludeIds,
|
|
31
|
+
}: UseQueryAutocompleteOptions ): UseQueryAutocompleteResult {
|
|
32
|
+
const excludeIdSet = useMemo( () => new Set( ( excludeIds ?? [] ).map( String ) ), [ excludeIds ] );
|
|
33
|
+
|
|
34
|
+
const [ options, setOptions ] = useState< FlatOption[] | CategorizedOption[] >(
|
|
35
|
+
generateFirstLoadedOption( initialQueryValue )
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const debounceFetch = useMemo(
|
|
39
|
+
() =>
|
|
40
|
+
debounce(
|
|
41
|
+
( queryParams: FetchOptionsParams ) =>
|
|
42
|
+
fetchOptions( url, queryParams ).then( ( newOptions ) => {
|
|
43
|
+
setOptions( formatOptions( filterExcludedOptions( newOptions, excludeIdSet ) ) );
|
|
44
|
+
} ),
|
|
45
|
+
400
|
|
46
|
+
),
|
|
47
|
+
[ url, excludeIdSet ]
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const updateOptions = ( term: string | null ) => {
|
|
51
|
+
setOptions( [] );
|
|
52
|
+
|
|
53
|
+
if ( ! term || ! url || term.length < minInputLength ) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
debounceFetch( { ...params, term } );
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
return { options, updateOptions };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function fetchOptions( ajaxUrl: string, params: FetchOptionsParams ) {
|
|
64
|
+
if ( ! params || ! ajaxUrl ) {
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const { data: response } = await httpService().get< Response >( ajaxUrl, { params } );
|
|
70
|
+
|
|
71
|
+
return response.data.value;
|
|
72
|
+
} catch {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function formatOptions( options: FlatOption[] | CategorizedOption[] ): FlatOption[] | CategorizedOption[] {
|
|
78
|
+
const compareKey = isCategorizedOptionPool( options ) ? 'groupLabel' : 'label';
|
|
79
|
+
|
|
80
|
+
return options.sort( ( a, b ) =>
|
|
81
|
+
a[ compareKey ] && b[ compareKey ] ? a[ compareKey ].localeCompare( b[ compareKey ] ) : 0
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function filterExcludedOptions(
|
|
86
|
+
options: FlatOption[] | CategorizedOption[],
|
|
87
|
+
excludeIdSet: Set< string >
|
|
88
|
+
): FlatOption[] | CategorizedOption[] {
|
|
89
|
+
if ( excludeIdSet.size === 0 ) {
|
|
90
|
+
return options;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return options.filter( ( option ) => ! excludeIdSet.has( String( option.id ) ) ) as
|
|
94
|
+
| FlatOption[]
|
|
95
|
+
| CategorizedOption[];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function extractFlatOptionFromQueryValue(
|
|
99
|
+
queryValue: QueryPropValue[ 'value' ] | null | undefined
|
|
100
|
+
): FlatOption | null {
|
|
101
|
+
const id = numberPropTypeUtil.extract( queryValue?.id );
|
|
102
|
+
const label = stringPropTypeUtil.extract( queryValue?.label );
|
|
103
|
+
|
|
104
|
+
if ( id === null ) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
id: String( id ),
|
|
110
|
+
label: label || String( id ),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function generateFirstLoadedOption( queryValue: QueryPropValue[ 'value' ] | null ): FlatOption[] {
|
|
115
|
+
const option = extractFlatOptionFromQueryValue( queryValue );
|
|
116
|
+
|
|
117
|
+
return option ? [ option ] : [];
|
|
118
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -20,6 +20,7 @@ export { ItemSelector } from './components/item-selector';
|
|
|
20
20
|
export { UrlControl } from './controls/url-control';
|
|
21
21
|
export { LinkControl } from './controls/link-control';
|
|
22
22
|
export { HtmlTagControl } from './controls/html-tag-control';
|
|
23
|
+
export { QueryChipsControl } from './controls/query-chips-control';
|
|
23
24
|
export { QueryControl } from './controls/query-control';
|
|
24
25
|
export { GapControl } from './controls/gap-control';
|
|
25
26
|
export { AspectRatioControl } from './controls/aspect-ratio-control';
|