@elementor/editor-controls 4.3.4 → 4.3.5
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 +10 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.js +2431 -1698
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2093 -1362
- package/dist/index.mjs.map +1 -1
- package/package.json +18 -18
- package/src/controls/color-control.tsx +5 -0
- package/src/controls/email-form-action-control/fields.tsx +27 -2
- package/src/controls/icon-library/custom-icon-libraries.ts +556 -0
- package/src/controls/icon-library/font-awesome-7-catalog.ts +16 -7
- package/src/controls/icon-library/font-awesome-7-data.ts +2 -0
- package/src/controls/icon-library/font-awesome-glyph.tsx +62 -17
- package/src/controls/icon-library/fontello-svg-font.ts +227 -0
- package/src/controls/icon-library/icomoon-selection.ts +104 -0
- package/src/controls/icon-library/icon-library-filter.tsx +142 -68
- package/src/controls/icon-library/icon-library-grid.tsx +19 -15
- package/src/controls/icon-library/icon-library-popover.tsx +31 -15
- package/src/controls/icon-library/icon-library-view-toggle.tsx +22 -82
- package/src/controls/icon-library/sanitize-icon-svg-markup.ts +53 -0
- package/src/controls/icon-library/svg-element-icon.tsx +15 -0
- package/src/controls/image-control.tsx +3 -3
- package/src/controls/image-media-control.tsx +15 -33
- package/src/controls/media-select-actions.tsx +105 -0
- package/src/controls/notice-control.tsx +11 -1
- package/src/controls/svg-media-control.tsx +4 -1
- package/src/controls/svg-media-overlay.tsx +24 -76
- package/src/controls/svg-media-preview.tsx +7 -2
- package/src/controls/video-media-control.tsx +13 -30
- package/src/index.ts +1 -0
|
@@ -24,7 +24,7 @@ export const ImageControl = createControl( ( { sizes, label = __( 'Image', 'elem
|
|
|
24
24
|
<PropProvider { ...propContext }>
|
|
25
25
|
<Stack gap={ 1.5 }>
|
|
26
26
|
<ControlLabel>{ label }</ControlLabel>
|
|
27
|
-
<ImageSrcControl />
|
|
27
|
+
<ImageSrcControl label={ label } />
|
|
28
28
|
<Grid container gap={ 1.5 } alignItems="center" flexWrap="nowrap">
|
|
29
29
|
<Grid item xs={ 6 }>
|
|
30
30
|
<ControlFormLabel>{ __( 'Resolution', 'elementor' ) }</ControlFormLabel>
|
|
@@ -38,13 +38,13 @@ export const ImageControl = createControl( ( { sizes, label = __( 'Image', 'elem
|
|
|
38
38
|
);
|
|
39
39
|
} );
|
|
40
40
|
|
|
41
|
-
const ImageSrcControl = () => {
|
|
41
|
+
const ImageSrcControl = ( { label }: { label: string } ) => {
|
|
42
42
|
const { data: allowSvgUpload } = useUnfilteredFilesUpload();
|
|
43
43
|
const mediaTypes: MediaType[] = allowSvgUpload ? [ 'image', 'svg' ] : [ 'image' ];
|
|
44
44
|
|
|
45
45
|
return (
|
|
46
46
|
<PropKeyProvider bind={ 'src' }>
|
|
47
|
-
<ImageMediaControl mediaTypes={ mediaTypes } />
|
|
47
|
+
<ImageMediaControl mediaTypes={ mediaTypes } label={ label } />
|
|
48
48
|
</PropKeyProvider>
|
|
49
49
|
);
|
|
50
50
|
};
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { imageSrcPropTypeUtil, stringPropTypeUtil, urlPropTypeUtil } from '@elementor/editor-props';
|
|
3
|
-
import {
|
|
4
|
-
import { Button, Card, CardMedia, CardOverlay, CircularProgress, Stack } from '@elementor/ui';
|
|
3
|
+
import { Card, CardMedia, CardOverlay, CircularProgress, Stack } from '@elementor/ui';
|
|
5
4
|
import { type MediaType, useWpMediaAttachment, useWpMediaFrame } from '@elementor/wp-media';
|
|
6
5
|
import { __ } from '@wordpress/i18n';
|
|
7
6
|
|
|
8
7
|
import { useBoundProp } from '../bound-prop-context';
|
|
9
8
|
import ControlActions from '../control-actions/control-actions';
|
|
10
9
|
import { createControl } from '../create-control';
|
|
10
|
+
import { MediaSelectActions } from './media-select-actions';
|
|
11
11
|
|
|
12
12
|
type ImageMediaControlProps = {
|
|
13
13
|
mediaTypes?: MediaType[];
|
|
14
|
+
label?: string;
|
|
14
15
|
};
|
|
15
16
|
|
|
16
|
-
export const ImageMediaControl = createControl( ( { mediaTypes
|
|
17
|
+
export const ImageMediaControl = createControl( ( { mediaTypes, label }: ImageMediaControlProps ) => {
|
|
18
|
+
const resolvedMediaTypes = mediaTypes ?? [ 'image' ];
|
|
19
|
+
const groupLabel = label ?? __( 'Image', 'elementor' );
|
|
17
20
|
const { value, setValue, propType, placeholder } = useBoundProp( imageSrcPropTypeUtil );
|
|
18
21
|
const { id, url } = value ?? {};
|
|
19
22
|
|
|
@@ -26,7 +29,7 @@ export const ImageMediaControl = createControl( ( { mediaTypes = [ 'image' ] }:
|
|
|
26
29
|
const currentAltForModal = ( value as { alt?: { value?: string } | null } | null | undefined )?.alt?.value;
|
|
27
30
|
|
|
28
31
|
const { open } = useWpMediaFrame( {
|
|
29
|
-
mediaTypes,
|
|
32
|
+
mediaTypes: resolvedMediaTypes,
|
|
30
33
|
multiple: false,
|
|
31
34
|
selected: id?.value || null,
|
|
32
35
|
allowUrlImport: true,
|
|
@@ -61,35 +64,14 @@ export const ImageMediaControl = createControl( ( { mediaTypes = [ 'image' ] }:
|
|
|
61
64
|
) }
|
|
62
65
|
</CardMedia>
|
|
63
66
|
<CardOverlay>
|
|
64
|
-
<
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
</Button>
|
|
73
|
-
<Button
|
|
74
|
-
size="tiny"
|
|
75
|
-
variant="text"
|
|
76
|
-
color="inherit"
|
|
77
|
-
startIcon={ <UploadIcon /> }
|
|
78
|
-
onClick={ () => open( { mode: 'upload' } ) }
|
|
79
|
-
>
|
|
80
|
-
{ __( 'Upload', 'elementor' ) }
|
|
81
|
-
</Button>
|
|
82
|
-
<Button
|
|
83
|
-
size="tiny"
|
|
84
|
-
variant="text"
|
|
85
|
-
color="inherit"
|
|
86
|
-
onClick={ () =>
|
|
87
|
-
open( { mode: 'url', currentUrl: currentUrlForModal, currentAlt: currentAltForModal } )
|
|
88
|
-
}
|
|
89
|
-
>
|
|
90
|
-
{ __( 'Insert from URL', 'elementor' ) }
|
|
91
|
-
</Button>
|
|
92
|
-
</Stack>
|
|
67
|
+
<MediaSelectActions
|
|
68
|
+
label={ groupLabel }
|
|
69
|
+
onSelect={ () => open( { mode: 'browse' } ) }
|
|
70
|
+
onUpload={ () => open( { mode: 'upload' } ) }
|
|
71
|
+
onInsertUrl={ () =>
|
|
72
|
+
open( { mode: 'url', currentUrl: currentUrlForModal, currentAlt: currentAltForModal } )
|
|
73
|
+
}
|
|
74
|
+
/>
|
|
93
75
|
</CardOverlay>
|
|
94
76
|
</Card>
|
|
95
77
|
</ControlActions>
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { UploadIcon } from '@elementor/icons';
|
|
3
|
+
import { Box, Button, Stack, styled } from '@elementor/ui';
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
|
|
6
|
+
const SELECT_AREA_WIDTH = 72;
|
|
7
|
+
const UPLOAD_AREA_WIDTH = 48;
|
|
8
|
+
const SPLIT_BUTTON_MIN_HEIGHT = 32;
|
|
9
|
+
const SPLIT_BUTTON_CORNER_RADIUS = '8px';
|
|
10
|
+
const SPLIT_BUTTON_FONT_SIZE = '14px';
|
|
11
|
+
|
|
12
|
+
const actionButtonSx = {
|
|
13
|
+
minWidth: 0,
|
|
14
|
+
minHeight: SPLIT_BUTTON_MIN_HEIGHT,
|
|
15
|
+
px: 2,
|
|
16
|
+
fontSize: SPLIT_BUTTON_FONT_SIZE,
|
|
17
|
+
fontWeight: 500,
|
|
18
|
+
lineHeight: 1,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const SplitButtonGroup = styled( Stack )( {
|
|
22
|
+
display: 'inline-flex',
|
|
23
|
+
flexDirection: 'row',
|
|
24
|
+
alignItems: 'stretch',
|
|
25
|
+
border: '1px solid currentColor',
|
|
26
|
+
borderRadius: SPLIT_BUTTON_CORNER_RADIUS,
|
|
27
|
+
overflow: 'hidden',
|
|
28
|
+
'& .MuiButton-root': {
|
|
29
|
+
border: 'none',
|
|
30
|
+
borderRadius: 0,
|
|
31
|
+
lineHeight: 1,
|
|
32
|
+
},
|
|
33
|
+
} );
|
|
34
|
+
|
|
35
|
+
type MediaActionGroupProps = {
|
|
36
|
+
label: string;
|
|
37
|
+
onSelect: () => void;
|
|
38
|
+
uploadSlot: React.ReactNode;
|
|
39
|
+
groupRef?: React.Ref< HTMLDivElement >;
|
|
40
|
+
testId?: string;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const MediaActionGroup = ( { label, onSelect, uploadSlot, groupRef, testId }: MediaActionGroupProps ) => (
|
|
44
|
+
<SplitButtonGroup ref={ groupRef } role="group" aria-label={ label } direction="row" data-testid={ testId }>
|
|
45
|
+
<Button
|
|
46
|
+
size="tiny"
|
|
47
|
+
color="inherit"
|
|
48
|
+
variant="text"
|
|
49
|
+
onClick={ onSelect }
|
|
50
|
+
sx={ { ...actionButtonSx, minWidth: SELECT_AREA_WIDTH } }
|
|
51
|
+
>
|
|
52
|
+
{ __( 'Select', 'elementor' ) }
|
|
53
|
+
</Button>
|
|
54
|
+
<Box
|
|
55
|
+
sx={ {
|
|
56
|
+
width: '1px',
|
|
57
|
+
alignSelf: 'stretch',
|
|
58
|
+
bgcolor: 'currentColor',
|
|
59
|
+
flexShrink: 0,
|
|
60
|
+
} }
|
|
61
|
+
/>
|
|
62
|
+
<Box component="span" sx={ { display: 'flex', width: UPLOAD_AREA_WIDTH } }>
|
|
63
|
+
{ uploadSlot }
|
|
64
|
+
</Box>
|
|
65
|
+
</SplitButtonGroup>
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
type MediaUploadButtonProps = {
|
|
69
|
+
disabled?: boolean;
|
|
70
|
+
onClick?: () => void;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const MediaUploadButton = ( { disabled = false, onClick }: MediaUploadButtonProps ) => (
|
|
74
|
+
<Button
|
|
75
|
+
sx={ { ...actionButtonSx, width: '100%' } }
|
|
76
|
+
size="tiny"
|
|
77
|
+
color="inherit"
|
|
78
|
+
variant="text"
|
|
79
|
+
disabled={ disabled }
|
|
80
|
+
onClick={ onClick }
|
|
81
|
+
aria-label={ __( 'Upload', 'elementor' ) }
|
|
82
|
+
>
|
|
83
|
+
<UploadIcon fontSize="small" />
|
|
84
|
+
</Button>
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
type MediaSelectActionsProps = {
|
|
88
|
+
label: string;
|
|
89
|
+
onSelect: () => void;
|
|
90
|
+
onUpload: () => void;
|
|
91
|
+
onInsertUrl: () => void;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export const MediaSelectActions = ( { label, onSelect, onUpload, onInsertUrl }: MediaSelectActionsProps ) => (
|
|
95
|
+
<Stack alignItems="center" gap={ 1 }>
|
|
96
|
+
<MediaActionGroup
|
|
97
|
+
label={ label }
|
|
98
|
+
onSelect={ onSelect }
|
|
99
|
+
uploadSlot={ <MediaUploadButton onClick={ onUpload } /> }
|
|
100
|
+
/>
|
|
101
|
+
<Button size="tiny" variant="text" color="inherit" onClick={ onInsertUrl }>
|
|
102
|
+
{ __( 'Insert URL', 'elementor' ) }
|
|
103
|
+
</Button>
|
|
104
|
+
</Stack>
|
|
105
|
+
);
|
|
@@ -45,9 +45,19 @@ const markNoticeAsDismissedInSession = ( dismissId: string ) => {
|
|
|
45
45
|
}
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
+
const isNoticeDismissed = ( dismissId?: string ) => {
|
|
49
|
+
if ( ! dismissId ) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const dismissedNotices = ( window as ExtendedWindow ).elementor?.config?.user?.dismissed_editor_notices;
|
|
54
|
+
|
|
55
|
+
return !! dismissedNotices?.includes( dismissId );
|
|
56
|
+
};
|
|
57
|
+
|
|
48
58
|
export const NoticeControl = createControl(
|
|
49
59
|
( { noticeType = 'info', heading, content, dismissible, buttonText, buttonUrl }: NoticeControlProps ) => {
|
|
50
|
-
const [ isDismissed, setIsDismissed ] = useState(
|
|
60
|
+
const [ isDismissed, setIsDismissed ] = useState( () => isNoticeDismissed( dismissible ) );
|
|
51
61
|
|
|
52
62
|
if ( isDismissed || ! content ) {
|
|
53
63
|
return null;
|
|
@@ -51,9 +51,11 @@ const MODE_UPLOAD: OpenOptions = { mode: 'upload' };
|
|
|
51
51
|
|
|
52
52
|
type SvgMediaControlProps = {
|
|
53
53
|
showIconLibrary?: boolean;
|
|
54
|
+
label?: string;
|
|
54
55
|
};
|
|
55
56
|
|
|
56
|
-
export const SvgMediaControl = createControl( ( { showIconLibrary = false }: SvgMediaControlProps ) => {
|
|
57
|
+
export const SvgMediaControl = createControl( ( { showIconLibrary = false, label }: SvgMediaControlProps ) => {
|
|
58
|
+
const groupLabel = label ?? __( 'SVG', 'elementor' );
|
|
57
59
|
const { value: svgValue, setValue: setSvgValue } = useBoundProp( svgSrcPropTypeUtil );
|
|
58
60
|
const { value: iconValue, setValue: setIconValue } = useBoundProp( iconPropTypeUtil );
|
|
59
61
|
const id = svgValue?.id;
|
|
@@ -208,6 +210,7 @@ export const SvgMediaControl = createControl( ( { showIconLibrary = false }: Svg
|
|
|
208
210
|
} }
|
|
209
211
|
>
|
|
210
212
|
<SvgMediaOverlay
|
|
213
|
+
label={ groupLabel }
|
|
211
214
|
isAdmin={ isAdmin }
|
|
212
215
|
showIconLibrary={ showIconLibrary }
|
|
213
216
|
buttonGroupRef={ buttonGroupRef }
|
|
@@ -1,37 +1,18 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { LibraryIcon
|
|
3
|
-
import { Box, Button, Stack,
|
|
2
|
+
import { LibraryIcon } from '@elementor/icons';
|
|
3
|
+
import { Box, Button, Stack, ThemeProvider, Typography } from '@elementor/ui';
|
|
4
4
|
import { __ } from '@wordpress/i18n';
|
|
5
5
|
|
|
6
6
|
import { ConditionalControlInfotip } from '../components/conditional-control-infotip';
|
|
7
|
+
import { MediaActionGroup, MediaUploadButton } from './media-select-actions';
|
|
7
8
|
|
|
8
9
|
export const SVG_MEDIA_CONTROL_CONTAINER_TEST_ID = 'svg-media-control-container';
|
|
9
10
|
export const SVG_MEDIA_ACTION_GROUP_TEST_ID = 'svg-media-action-group';
|
|
10
11
|
|
|
11
|
-
const MEDIA_ACTION_PADDING_Y = 0.75;
|
|
12
|
-
const MEDIA_ACTION_PADDING_X = 2;
|
|
13
12
|
const ICON_LIBRARY_PADDING = 0.625;
|
|
14
13
|
|
|
15
|
-
const svgButtonSx = {
|
|
16
|
-
px: MEDIA_ACTION_PADDING_X,
|
|
17
|
-
py: MEDIA_ACTION_PADDING_Y,
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const MediaActionGroup = styled( Stack )( ( { theme } ) => ( {
|
|
21
|
-
display: 'inline-flex',
|
|
22
|
-
flexDirection: 'row',
|
|
23
|
-
alignItems: 'stretch',
|
|
24
|
-
border: '1px solid currentColor',
|
|
25
|
-
borderRadius: theme.shape.borderRadius,
|
|
26
|
-
overflow: 'hidden',
|
|
27
|
-
'& .MuiButton-root': {
|
|
28
|
-
border: 'none',
|
|
29
|
-
borderRadius: 0,
|
|
30
|
-
lineHeight: 1,
|
|
31
|
-
},
|
|
32
|
-
} ) );
|
|
33
|
-
|
|
34
14
|
type SvgMediaOverlayProps = {
|
|
15
|
+
label: string;
|
|
35
16
|
isAdmin: boolean;
|
|
36
17
|
showIconLibrary: boolean;
|
|
37
18
|
buttonGroupRef: React.Ref< HTMLDivElement >;
|
|
@@ -43,6 +24,7 @@ type SvgMediaOverlayProps = {
|
|
|
43
24
|
};
|
|
44
25
|
|
|
45
26
|
export const SvgMediaOverlay = ( {
|
|
27
|
+
label,
|
|
46
28
|
isAdmin,
|
|
47
29
|
showIconLibrary,
|
|
48
30
|
buttonGroupRef,
|
|
@@ -53,35 +35,23 @@ export const SvgMediaOverlay = ( {
|
|
|
53
35
|
infotipDescription,
|
|
54
36
|
}: SvgMediaOverlayProps ) => (
|
|
55
37
|
<Stack alignItems="center" gap={ 1 }>
|
|
56
|
-
<MediaActionGroup
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
} }
|
|
74
|
-
/>
|
|
75
|
-
<ConditionalControlInfotip
|
|
76
|
-
title={ infotipTitle }
|
|
77
|
-
description={ infotipDescription }
|
|
78
|
-
isEnabled={ ! isAdmin }
|
|
79
|
-
>
|
|
80
|
-
<Box component="span" sx={ { display: 'inline-flex' } }>
|
|
81
|
-
<UploadControl isAdmin={ isAdmin } onUpload={ onUpload } />
|
|
82
|
-
</Box>
|
|
83
|
-
</ConditionalControlInfotip>
|
|
84
|
-
</MediaActionGroup>
|
|
38
|
+
<MediaActionGroup
|
|
39
|
+
label={ label }
|
|
40
|
+
onSelect={ onSelectSvg }
|
|
41
|
+
groupRef={ buttonGroupRef }
|
|
42
|
+
testId={ SVG_MEDIA_ACTION_GROUP_TEST_ID }
|
|
43
|
+
uploadSlot={
|
|
44
|
+
<ConditionalControlInfotip
|
|
45
|
+
title={ infotipTitle }
|
|
46
|
+
description={ infotipDescription }
|
|
47
|
+
isEnabled={ ! isAdmin }
|
|
48
|
+
>
|
|
49
|
+
<Box component="span" sx={ { display: 'flex', width: '100%' } }>
|
|
50
|
+
<UploadControl isAdmin={ isAdmin } onUpload={ onUpload } />
|
|
51
|
+
</Box>
|
|
52
|
+
</ConditionalControlInfotip>
|
|
53
|
+
}
|
|
54
|
+
/>
|
|
85
55
|
{ showIconLibrary ? (
|
|
86
56
|
<Button
|
|
87
57
|
size="tiny"
|
|
@@ -104,34 +74,12 @@ export const SvgMediaOverlay = ( {
|
|
|
104
74
|
|
|
105
75
|
const UploadControl = ( { isAdmin, onUpload }: { isAdmin: boolean; onUpload: () => void } ) => {
|
|
106
76
|
if ( isAdmin ) {
|
|
107
|
-
return <
|
|
77
|
+
return <MediaUploadButton onClick={ onUpload } />;
|
|
108
78
|
}
|
|
109
79
|
|
|
110
80
|
return (
|
|
111
81
|
<ThemeProvider colorScheme="dark">
|
|
112
|
-
<
|
|
82
|
+
<MediaUploadButton disabled />
|
|
113
83
|
</ThemeProvider>
|
|
114
84
|
);
|
|
115
85
|
};
|
|
116
|
-
|
|
117
|
-
const UploadButton = ( {
|
|
118
|
-
disabled = false,
|
|
119
|
-
sx,
|
|
120
|
-
onClick,
|
|
121
|
-
}: {
|
|
122
|
-
disabled?: boolean;
|
|
123
|
-
sx?: SxProps;
|
|
124
|
-
onClick?: () => void;
|
|
125
|
-
} ) => (
|
|
126
|
-
<Button
|
|
127
|
-
sx={ sx }
|
|
128
|
-
size="tiny"
|
|
129
|
-
color="inherit"
|
|
130
|
-
variant="text"
|
|
131
|
-
disabled={ disabled }
|
|
132
|
-
onClick={ onClick }
|
|
133
|
-
aria-label={ __( 'Upload', 'elementor' ) }
|
|
134
|
-
>
|
|
135
|
-
<UploadIcon />
|
|
136
|
-
</Button>
|
|
137
|
-
);
|
|
@@ -2,6 +2,7 @@ import * as React from 'react';
|
|
|
2
2
|
import { Box, CardMedia, CircularProgress } from '@elementor/ui';
|
|
3
3
|
import { __ } from '@wordpress/i18n';
|
|
4
4
|
|
|
5
|
+
import { useCustomIconLibraries } from './icon-library/custom-icon-libraries';
|
|
5
6
|
import { findFontAwesome7Icon, type FontAwesome7Icon } from './icon-library/font-awesome-7-catalog';
|
|
6
7
|
import { FontAwesomeGlyph } from './icon-library/font-awesome-glyph';
|
|
7
8
|
import { useFontAwesome7Catalog } from './icon-library/use-font-awesome-7-catalog';
|
|
@@ -18,10 +19,14 @@ type SvgMediaPreviewProps = {
|
|
|
18
19
|
|
|
19
20
|
export const SvgMediaPreview = ( { isFetching, src, iconClassName, iconLibrary }: SvgMediaPreviewProps ) => {
|
|
20
21
|
const shouldLoadIconCatalog = Boolean( iconClassName && iconLibrary );
|
|
21
|
-
const { data:
|
|
22
|
+
const { data: fontAwesomeIcons = [], isLoading: isFontAwesomeLoading } =
|
|
23
|
+
useFontAwesome7Catalog( shouldLoadIconCatalog );
|
|
24
|
+
const { data: customIcons = [], isLoading: isCustomLoading } = useCustomIconLibraries( shouldLoadIconCatalog );
|
|
25
|
+
const icons = [ ...fontAwesomeIcons, ...customIcons ];
|
|
22
26
|
const selectedIcon = findFontAwesome7Icon( icons, iconClassName, iconLibrary );
|
|
27
|
+
const isLoadingCatalog = shouldLoadIconCatalog && ( isFontAwesomeLoading || isCustomLoading );
|
|
23
28
|
|
|
24
|
-
if ( isFetching ||
|
|
29
|
+
if ( isFetching || isLoadingCatalog ) {
|
|
25
30
|
return <CircularProgress role="progressbar" />;
|
|
26
31
|
}
|
|
27
32
|
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { urlPropTypeUtil, videoSrcPropTypeUtil } from '@elementor/editor-props';
|
|
3
|
-
import {
|
|
4
|
-
import { Button, Card, CardMedia, CardOverlay, CircularProgress, Stack } from '@elementor/ui';
|
|
3
|
+
import { Card, CardMedia, CardOverlay, CircularProgress } from '@elementor/ui';
|
|
5
4
|
import { useWpMediaAttachment, useWpMediaFrame } from '@elementor/wp-media';
|
|
6
5
|
import { __ } from '@wordpress/i18n';
|
|
7
6
|
|
|
8
7
|
import { useBoundProp } from '../bound-prop-context';
|
|
9
8
|
import ControlActions from '../control-actions/control-actions';
|
|
10
9
|
import { createControl } from '../create-control';
|
|
10
|
+
import { MediaSelectActions } from './media-select-actions';
|
|
11
11
|
import { TILES_GRADIENT_FORMULA } from './svg-media-control';
|
|
12
12
|
|
|
13
13
|
const PLACEHOLDER_IMAGE = window.elementorCommon?.config?.urls?.assets + '/shapes/play-triangle.svg';
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
type VideoMediaControlProps = {
|
|
16
|
+
label?: string;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const VideoMediaControl = createControl( ( { label = __( 'Video', 'elementor' ) }: VideoMediaControlProps ) => {
|
|
16
20
|
const { value, setValue, propType } = useBoundProp( videoSrcPropTypeUtil );
|
|
17
21
|
const { id, url } = value ?? {};
|
|
18
22
|
|
|
@@ -63,33 +67,12 @@ export const VideoMediaControl = createControl( () => {
|
|
|
63
67
|
<VideoPreview isFetching={ isFetching } videoUrl={ videoUrl } />
|
|
64
68
|
</CardMedia>
|
|
65
69
|
<CardOverlay>
|
|
66
|
-
<
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
>
|
|
73
|
-
{ __( 'Select video', 'elementor' ) }
|
|
74
|
-
</Button>
|
|
75
|
-
<Button
|
|
76
|
-
size="tiny"
|
|
77
|
-
variant="text"
|
|
78
|
-
color="inherit"
|
|
79
|
-
startIcon={ <UploadIcon /> }
|
|
80
|
-
onClick={ () => open( { mode: 'upload' } ) }
|
|
81
|
-
>
|
|
82
|
-
{ __( 'Upload', 'elementor' ) }
|
|
83
|
-
</Button>
|
|
84
|
-
<Button
|
|
85
|
-
size="tiny"
|
|
86
|
-
variant="text"
|
|
87
|
-
color="inherit"
|
|
88
|
-
onClick={ () => open( { mode: 'url', currentUrl: currentUrlForModal } ) }
|
|
89
|
-
>
|
|
90
|
-
{ __( 'Insert from URL', 'elementor' ) }
|
|
91
|
-
</Button>
|
|
92
|
-
</Stack>
|
|
70
|
+
<MediaSelectActions
|
|
71
|
+
label={ label }
|
|
72
|
+
onSelect={ () => open( { mode: 'browse' } ) }
|
|
73
|
+
onUpload={ () => open( { mode: 'upload' } ) }
|
|
74
|
+
onInsertUrl={ () => open( { mode: 'url', currentUrl: currentUrlForModal } ) }
|
|
75
|
+
/>
|
|
93
76
|
</CardOverlay>
|
|
94
77
|
</Card>
|
|
95
78
|
</ControlActions>
|
package/src/index.ts
CHANGED
|
@@ -37,6 +37,7 @@ export { TransformSettingsControl } from './controls/transform-control/transform
|
|
|
37
37
|
export { TransitionRepeaterControl } from './controls/transition-control/transition-repeater-control';
|
|
38
38
|
export { PopoverContent } from './components/popover-content';
|
|
39
39
|
export { enqueueFont } from './controls/font-family-control/enqueue-font';
|
|
40
|
+
export { isDeletedCustomIconLibrary, resolveCustomIconSvg } from './controls/icon-library/custom-icon-libraries';
|
|
40
41
|
export {
|
|
41
42
|
getFontAwesome7IconName,
|
|
42
43
|
resetFontAwesome7IconsCache,
|