@elementor/editor-controls 0.14.0 → 0.16.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/CHANGELOG.md +30 -0
- package/dist/index.d.mts +8 -3
- package/dist/index.d.ts +8 -3
- package/dist/index.js +480 -221
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +485 -217
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -6
- package/src/api.ts +16 -0
- package/src/components/repeater.tsx +20 -23
- package/src/controls/background-control/background-gradient-color-control.tsx +101 -0
- package/src/controls/background-control/background-overlay/background-overlay-repeater-control.tsx +43 -5
- package/src/controls/background-control/background-overlay/use-background-tabs-history.ts +29 -2
- package/src/controls/equal-unequal-sizes-control.tsx +15 -10
- package/src/controls/font-family-control/enqueue-font.tsx +15 -0
- package/src/controls/font-family-control/font-family-control.tsx +302 -0
- package/src/controls/gap-control.tsx +19 -11
- package/src/controls/image-control.tsx +6 -1
- package/src/controls/image-media-control.tsx +4 -6
- package/src/controls/linked-dimensions-control.tsx +57 -25
- package/src/controls/svg-media-control.tsx +15 -5
- package/src/hooks/use-filtered-font-families.ts +13 -26
- package/src/hooks/use-unfiltered-files-upload.ts +40 -0
- package/src/index.ts +1 -1
- package/src/controls/font-family-control.tsx +0 -157
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useMutation, useQuery, useQueryClient } from '@elementor/query';
|
|
2
|
+
|
|
3
|
+
import { apiClient } from '../api';
|
|
4
|
+
|
|
5
|
+
export const UNFILTERED_FILES_UPLOAD_KEY = 'elementor_unfiltered_files_upload';
|
|
6
|
+
|
|
7
|
+
const unfilteredFilesQueryKey = {
|
|
8
|
+
queryKey: [ UNFILTERED_FILES_UPLOAD_KEY ],
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
type Value = '0' | '1';
|
|
12
|
+
|
|
13
|
+
export const useUnfilteredFilesUpload = () =>
|
|
14
|
+
useQuery( {
|
|
15
|
+
...unfilteredFilesQueryKey,
|
|
16
|
+
queryFn: (): Promise< boolean > =>
|
|
17
|
+
apiClient.getElementorSetting< Value >( UNFILTERED_FILES_UPLOAD_KEY ).then( ( res ) => {
|
|
18
|
+
return formatResponse( res );
|
|
19
|
+
} ),
|
|
20
|
+
staleTime: Infinity,
|
|
21
|
+
} );
|
|
22
|
+
|
|
23
|
+
export function useUpdateUnfilteredFilesUpload() {
|
|
24
|
+
const queryClient = useQueryClient();
|
|
25
|
+
|
|
26
|
+
const mutate = useMutation( {
|
|
27
|
+
mutationFn: ( { allowUnfilteredFilesUpload }: { allowUnfilteredFilesUpload: boolean } ) =>
|
|
28
|
+
apiClient.updateElementorSetting< Value >(
|
|
29
|
+
UNFILTERED_FILES_UPLOAD_KEY,
|
|
30
|
+
allowUnfilteredFilesUpload ? '1' : '0'
|
|
31
|
+
),
|
|
32
|
+
onSuccess: () => queryClient.invalidateQueries( unfilteredFilesQueryKey ),
|
|
33
|
+
} );
|
|
34
|
+
|
|
35
|
+
return mutate;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const formatResponse = ( response: Value ): boolean => {
|
|
39
|
+
return Boolean( response === '1' );
|
|
40
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -11,7 +11,7 @@ export { ToggleControl } from './controls/toggle-control';
|
|
|
11
11
|
export { NumberControl } from './controls/number-control';
|
|
12
12
|
export { EqualUnequalSizesControl } from './controls/equal-unequal-sizes-control';
|
|
13
13
|
export { LinkedDimensionsControl } from './controls/linked-dimensions-control';
|
|
14
|
-
export { FontFamilyControl } from './controls/font-family-control';
|
|
14
|
+
export { FontFamilyControl } from './controls/font-family-control/font-family-control';
|
|
15
15
|
export { UrlControl } from './controls/url-control';
|
|
16
16
|
export { LinkControl } from './controls/link-control';
|
|
17
17
|
export { GapControl } from './controls/gap-control';
|
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import { Fragment, useId, useState } from 'react';
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
import { stringPropTypeUtil } from '@elementor/editor-props';
|
|
4
|
-
import { ChevronDownIcon, EditIcon, PhotoIcon, SearchIcon, XIcon } from '@elementor/icons';
|
|
5
|
-
import {
|
|
6
|
-
bindPopover,
|
|
7
|
-
bindTrigger,
|
|
8
|
-
Box,
|
|
9
|
-
Divider,
|
|
10
|
-
IconButton,
|
|
11
|
-
InputAdornment,
|
|
12
|
-
Link,
|
|
13
|
-
ListSubheader,
|
|
14
|
-
MenuItem,
|
|
15
|
-
MenuList,
|
|
16
|
-
Popover,
|
|
17
|
-
Stack,
|
|
18
|
-
TextField,
|
|
19
|
-
Typography,
|
|
20
|
-
UnstableTag,
|
|
21
|
-
usePopupState,
|
|
22
|
-
} from '@elementor/ui';
|
|
23
|
-
import { __ } from '@wordpress/i18n';
|
|
24
|
-
|
|
25
|
-
import { useBoundProp } from '../bound-prop-context';
|
|
26
|
-
import { createControl } from '../create-control';
|
|
27
|
-
import { useFilteredFontFamilies } from '../hooks/use-filtered-font-families';
|
|
28
|
-
|
|
29
|
-
const SIZE = 'tiny';
|
|
30
|
-
|
|
31
|
-
export const FontFamilyControl = createControl( ( { fontFamilies } ) => {
|
|
32
|
-
const [ searchValue, setSearchValue ] = useState( '' );
|
|
33
|
-
const { value: fontFamily, setValue: setFontFamily } = useBoundProp( stringPropTypeUtil );
|
|
34
|
-
|
|
35
|
-
const popupId = useId();
|
|
36
|
-
const popoverState = usePopupState( { variant: 'popover', popupId } );
|
|
37
|
-
|
|
38
|
-
const filteredFontFamilies = useFilteredFontFamilies( fontFamilies, searchValue );
|
|
39
|
-
|
|
40
|
-
if ( ! filteredFontFamilies ) {
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const handleSearch = ( event: React.ChangeEvent< HTMLInputElement > ) => {
|
|
45
|
-
setSearchValue( event.target.value );
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const handleClose = () => {
|
|
49
|
-
setSearchValue( '' );
|
|
50
|
-
|
|
51
|
-
popoverState.close();
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
return (
|
|
55
|
-
<>
|
|
56
|
-
<UnstableTag
|
|
57
|
-
variant="outlined"
|
|
58
|
-
label={ fontFamily }
|
|
59
|
-
endIcon={ <ChevronDownIcon fontSize="tiny" /> }
|
|
60
|
-
{ ...bindTrigger( popoverState ) }
|
|
61
|
-
fullWidth
|
|
62
|
-
/>
|
|
63
|
-
|
|
64
|
-
<Popover
|
|
65
|
-
disablePortal
|
|
66
|
-
disableScrollLock
|
|
67
|
-
anchorOrigin={ { vertical: 'bottom', horizontal: 'left' } }
|
|
68
|
-
{ ...bindPopover( popoverState ) }
|
|
69
|
-
onClose={ handleClose }
|
|
70
|
-
>
|
|
71
|
-
<Stack>
|
|
72
|
-
<Stack direction="row" alignItems="center" pl={ 1.5 } pr={ 0.5 } py={ 1.5 }>
|
|
73
|
-
<EditIcon fontSize={ SIZE } sx={ { mr: 0.5 } } />
|
|
74
|
-
<Typography variant="subtitle2">{ __( 'Font family', 'elementor' ) }</Typography>
|
|
75
|
-
<IconButton size={ SIZE } sx={ { ml: 'auto' } } onClick={ handleClose }>
|
|
76
|
-
<XIcon fontSize={ SIZE } />
|
|
77
|
-
</IconButton>
|
|
78
|
-
</Stack>
|
|
79
|
-
|
|
80
|
-
<Box px={ 1.5 } pb={ 1 }>
|
|
81
|
-
<TextField
|
|
82
|
-
fullWidth
|
|
83
|
-
size={ SIZE }
|
|
84
|
-
value={ searchValue }
|
|
85
|
-
placeholder={ __( 'Search fonts…', 'elementor' ) }
|
|
86
|
-
onChange={ handleSearch }
|
|
87
|
-
InputProps={ {
|
|
88
|
-
startAdornment: (
|
|
89
|
-
<InputAdornment position="start">
|
|
90
|
-
<SearchIcon fontSize={ SIZE } />
|
|
91
|
-
</InputAdornment>
|
|
92
|
-
),
|
|
93
|
-
} }
|
|
94
|
-
/>
|
|
95
|
-
</Box>
|
|
96
|
-
<Divider />
|
|
97
|
-
<Box sx={ { overflowY: 'auto', height: 260, width: 220 } }>
|
|
98
|
-
{ filteredFontFamilies.length > 0 ? (
|
|
99
|
-
<MenuList role="listbox" tabIndex={ 0 }>
|
|
100
|
-
{ filteredFontFamilies.map( ( [ category, items ], index ) => (
|
|
101
|
-
<Fragment key={ index }>
|
|
102
|
-
<ListSubheader
|
|
103
|
-
sx={ { px: 1.5, typography: 'caption', color: 'text.tertiary' } }
|
|
104
|
-
>
|
|
105
|
-
{ category }
|
|
106
|
-
</ListSubheader>
|
|
107
|
-
{ items.map( ( item ) => {
|
|
108
|
-
const isSelected = item === fontFamily;
|
|
109
|
-
|
|
110
|
-
return (
|
|
111
|
-
<MenuItem
|
|
112
|
-
key={ item }
|
|
113
|
-
selected={ isSelected }
|
|
114
|
-
// eslint-disable-next-line jsx-a11y/no-autofocus
|
|
115
|
-
autoFocus={ isSelected }
|
|
116
|
-
onClick={ () => {
|
|
117
|
-
setFontFamily( item );
|
|
118
|
-
handleClose();
|
|
119
|
-
} }
|
|
120
|
-
sx={ { px: 1.5, typography: 'caption' } }
|
|
121
|
-
style={ { fontFamily: item } }
|
|
122
|
-
>
|
|
123
|
-
{ item }
|
|
124
|
-
</MenuItem>
|
|
125
|
-
);
|
|
126
|
-
} ) }
|
|
127
|
-
</Fragment>
|
|
128
|
-
) ) }
|
|
129
|
-
</MenuList>
|
|
130
|
-
) : (
|
|
131
|
-
<Stack alignItems="center" p={ 2.5 } gap={ 1.5 }>
|
|
132
|
-
<PhotoIcon fontSize="large" />
|
|
133
|
-
<Typography align="center" variant="caption" color="text.secondary">
|
|
134
|
-
{ __( 'Sorry, nothing matched', 'elementor' ) }
|
|
135
|
-
<br />
|
|
136
|
-
“{ searchValue }”.
|
|
137
|
-
</Typography>
|
|
138
|
-
<Typography align="center" variant="caption" color="text.secondary">
|
|
139
|
-
<Link
|
|
140
|
-
color="secondary"
|
|
141
|
-
variant="caption"
|
|
142
|
-
component="button"
|
|
143
|
-
onClick={ () => setSearchValue( '' ) }
|
|
144
|
-
>
|
|
145
|
-
{ __( 'Clear the filters', 'elementor' ) }
|
|
146
|
-
</Link>
|
|
147
|
-
|
|
148
|
-
{ __( 'and try again.', 'elementor' ) }
|
|
149
|
-
</Typography>
|
|
150
|
-
</Stack>
|
|
151
|
-
) }
|
|
152
|
-
</Box>
|
|
153
|
-
</Stack>
|
|
154
|
-
</Popover>
|
|
155
|
-
</>
|
|
156
|
-
);
|
|
157
|
-
} );
|