@wordpress/edit-site 5.27.1 → 5.27.2
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/build/components/block-editor/back-button.js +2 -3
- package/build/components/block-editor/back-button.js.map +1 -1
- package/build/components/block-editor/site-editor-canvas.js +8 -2
- package/build/components/block-editor/site-editor-canvas.js.map +1 -1
- package/build/components/block-editor/use-post-link-props.js +5 -1
- package/build/components/block-editor/use-post-link-props.js.map +1 -1
- package/build/components/editor/index.js +7 -7
- package/build/components/editor/index.js.map +1 -1
- package/build/components/global-styles/font-library-modal/context.js +14 -0
- package/build/components/global-styles/font-library-modal/context.js.map +1 -1
- package/build/components/global-styles/font-library-modal/font-collection.js +17 -33
- package/build/components/global-styles/font-library-modal/font-collection.js.map +1 -1
- package/build/components/global-styles/font-library-modal/font-demo.js +1 -1
- package/build/components/global-styles/font-library-modal/font-demo.js.map +1 -1
- package/build/components/global-styles/font-library-modal/google-fonts-confirm-dialog.js +1 -1
- package/build/components/global-styles/font-library-modal/google-fonts-confirm-dialog.js.map +1 -1
- package/build/components/global-styles/font-library-modal/index.js +10 -3
- package/build/components/global-styles/font-library-modal/index.js.map +1 -1
- package/build/components/global-styles/font-library-modal/installed-fonts.js +8 -21
- package/build/components/global-styles/font-library-modal/installed-fonts.js.map +1 -1
- package/build/components/global-styles/font-library-modal/library-font-variant.js +2 -2
- package/build/components/global-styles/font-library-modal/library-font-variant.js.map +1 -1
- package/build/components/global-styles/font-library-modal/resolvers.js +1 -1
- package/build/components/global-styles/font-library-modal/resolvers.js.map +1 -1
- package/build/components/global-styles/font-library-modal/tab-panel-layout.js +9 -1
- package/build/components/global-styles/font-library-modal/tab-panel-layout.js.map +1 -1
- package/build/components/global-styles/font-library-modal/upload-fonts.js +160 -4
- package/build/components/global-styles/font-library-modal/upload-fonts.js.map +1 -1
- package/build/components/global-styles/font-library-modal/utils/index.js +33 -31
- package/build/components/global-styles/font-library-modal/utils/index.js.map +1 -1
- package/build/components/routes/link.js +1 -1
- package/build/components/routes/link.js.map +1 -1
- package/build/components/sidebar-edit-mode/index.js +1 -2
- package/build/components/sidebar-edit-mode/index.js.map +1 -1
- package/build/components/sidebar-edit-mode/settings-header/index.js +7 -36
- package/build/components/sidebar-edit-mode/settings-header/index.js.map +1 -1
- package/build/components/welcome-guide/template.js +2 -2
- package/build/components/welcome-guide/template.js.map +1 -1
- package/build/hooks/commands/use-edit-mode-commands.js +16 -6
- package/build/hooks/commands/use-edit-mode-commands.js.map +1 -1
- package/build-module/components/block-editor/back-button.js +2 -3
- package/build-module/components/block-editor/back-button.js.map +1 -1
- package/build-module/components/block-editor/site-editor-canvas.js +8 -2
- package/build-module/components/block-editor/site-editor-canvas.js.map +1 -1
- package/build-module/components/block-editor/use-post-link-props.js +5 -1
- package/build-module/components/block-editor/use-post-link-props.js.map +1 -1
- package/build-module/components/editor/index.js +7 -7
- package/build-module/components/editor/index.js.map +1 -1
- package/build-module/components/global-styles/font-library-modal/context.js +14 -0
- package/build-module/components/global-styles/font-library-modal/context.js.map +1 -1
- package/build-module/components/global-styles/font-library-modal/font-collection.js +19 -35
- package/build-module/components/global-styles/font-library-modal/font-collection.js.map +1 -1
- package/build-module/components/global-styles/font-library-modal/font-demo.js +1 -1
- package/build-module/components/global-styles/font-library-modal/font-demo.js.map +1 -1
- package/build-module/components/global-styles/font-library-modal/google-fonts-confirm-dialog.js +1 -1
- package/build-module/components/global-styles/font-library-modal/google-fonts-confirm-dialog.js.map +1 -1
- package/build-module/components/global-styles/font-library-modal/index.js +10 -3
- package/build-module/components/global-styles/font-library-modal/index.js.map +1 -1
- package/build-module/components/global-styles/font-library-modal/installed-fonts.js +9 -22
- package/build-module/components/global-styles/font-library-modal/installed-fonts.js.map +1 -1
- package/build-module/components/global-styles/font-library-modal/library-font-variant.js +2 -2
- package/build-module/components/global-styles/font-library-modal/library-font-variant.js.map +1 -1
- package/build-module/components/global-styles/font-library-modal/resolvers.js +1 -1
- package/build-module/components/global-styles/font-library-modal/resolvers.js.map +1 -1
- package/build-module/components/global-styles/font-library-modal/tab-panel-layout.js +10 -2
- package/build-module/components/global-styles/font-library-modal/tab-panel-layout.js.map +1 -1
- package/build-module/components/global-styles/font-library-modal/upload-fonts.js +162 -6
- package/build-module/components/global-styles/font-library-modal/upload-fonts.js.map +1 -1
- package/build-module/components/global-styles/font-library-modal/utils/index.js +32 -30
- package/build-module/components/global-styles/font-library-modal/utils/index.js.map +1 -1
- package/build-module/components/routes/link.js +1 -1
- package/build-module/components/routes/link.js.map +1 -1
- package/build-module/components/sidebar-edit-mode/index.js +1 -2
- package/build-module/components/sidebar-edit-mode/index.js.map +1 -1
- package/build-module/components/sidebar-edit-mode/settings-header/index.js +7 -36
- package/build-module/components/sidebar-edit-mode/settings-header/index.js.map +1 -1
- package/build-module/components/welcome-guide/template.js +2 -2
- package/build-module/components/welcome-guide/template.js.map +1 -1
- package/build-module/hooks/commands/use-edit-mode-commands.js +16 -6
- package/build-module/hooks/commands/use-edit-mode-commands.js.map +1 -1
- package/build-style/style-rtl.css +4 -6
- package/build-style/style.css +4 -6
- package/package.json +11 -11
- package/src/components/block-editor/back-button.js +6 -3
- package/src/components/block-editor/site-editor-canvas.js +19 -12
- package/src/components/block-editor/use-post-link-props.js +5 -1
- package/src/components/editor/index.js +4 -9
- package/src/components/global-styles/font-library-modal/context.js +14 -0
- package/src/components/global-styles/font-library-modal/font-collection.js +16 -40
- package/src/components/global-styles/font-library-modal/font-demo.js +1 -1
- package/src/components/global-styles/font-library-modal/google-fonts-confirm-dialog.js +1 -1
- package/src/components/global-styles/font-library-modal/index.js +8 -3
- package/src/components/global-styles/font-library-modal/installed-fonts.js +12 -31
- package/src/components/global-styles/font-library-modal/library-font-variant.js +2 -2
- package/src/components/global-styles/font-library-modal/resolvers.js +1 -1
- package/src/components/global-styles/font-library-modal/style.scss +0 -10
- package/src/components/global-styles/font-library-modal/tab-panel-layout.js +15 -0
- package/src/components/global-styles/font-library-modal/upload-fonts.js +201 -6
- package/src/components/global-styles/font-library-modal/utils/index.js +44 -38
- package/src/components/routes/link.js +1 -1
- package/src/components/sidebar-edit-mode/index.js +1 -4
- package/src/components/sidebar-edit-mode/settings-header/index.js +12 -34
- package/src/components/welcome-guide/template.js +2 -2
- package/src/hooks/commands/use-edit-mode-commands.js +26 -14
- package/build/components/global-styles/font-library-modal/local-fonts.js +0 -196
- package/build/components/global-styles/font-library-modal/local-fonts.js.map +0 -1
- package/build-module/components/global-styles/font-library-modal/local-fonts.js +0 -187
- package/build-module/components/global-styles/font-library-modal/local-fonts.js.map +0 -1
- package/src/components/global-styles/font-library-modal/local-fonts.js +0 -239
|
@@ -102,13 +102,13 @@ export default function Editor( { isLoading } ) {
|
|
|
102
102
|
contextPost,
|
|
103
103
|
editorMode,
|
|
104
104
|
canvasMode,
|
|
105
|
-
renderingMode,
|
|
106
105
|
blockEditorMode,
|
|
107
106
|
isRightSidebarOpen,
|
|
108
107
|
isInserterOpen,
|
|
109
108
|
isListViewOpen,
|
|
110
109
|
showIconLabels,
|
|
111
110
|
showBlockBreadcrumbs,
|
|
111
|
+
postTypeLabel,
|
|
112
112
|
} = useSelect( ( select ) => {
|
|
113
113
|
const { get } = select( preferencesStore );
|
|
114
114
|
const { getEditedPostContext, getEditorMode, getCanvasMode } = unlock(
|
|
@@ -117,7 +117,7 @@ export default function Editor( { isLoading } ) {
|
|
|
117
117
|
const { __unstableGetEditorMode } = select( blockEditorStore );
|
|
118
118
|
const { getActiveComplementaryArea } = select( interfaceStore );
|
|
119
119
|
const { getEntityRecord } = select( coreDataStore );
|
|
120
|
-
const {
|
|
120
|
+
const { isInserterOpened, isListViewOpened, getPostTypeLabel } =
|
|
121
121
|
select( editorStore );
|
|
122
122
|
const _context = getEditedPostContext();
|
|
123
123
|
|
|
@@ -134,7 +134,6 @@ export default function Editor( { isLoading } ) {
|
|
|
134
134
|
: undefined,
|
|
135
135
|
editorMode: getEditorMode(),
|
|
136
136
|
canvasMode: getCanvasMode(),
|
|
137
|
-
renderingMode: getRenderingMode(),
|
|
138
137
|
blockEditorMode: __unstableGetEditorMode(),
|
|
139
138
|
isInserterOpen: isInserterOpened(),
|
|
140
139
|
isListViewOpen: isListViewOpened(),
|
|
@@ -143,6 +142,7 @@ export default function Editor( { isLoading } ) {
|
|
|
143
142
|
),
|
|
144
143
|
showBlockBreadcrumbs: get( 'core', 'showBlockBreadcrumbs' ),
|
|
145
144
|
showIconLabels: get( 'core', 'showIconLabels' ),
|
|
145
|
+
postTypeLabel: getPostTypeLabel(),
|
|
146
146
|
};
|
|
147
147
|
}, [] );
|
|
148
148
|
|
|
@@ -267,12 +267,7 @@ export default function Editor( { isLoading } ) {
|
|
|
267
267
|
footer={
|
|
268
268
|
shouldShowBlockBreadcrumbs && (
|
|
269
269
|
<BlockBreadcrumb
|
|
270
|
-
rootLabelText={
|
|
271
|
-
postWithTemplate &&
|
|
272
|
-
renderingMode !== 'template-only'
|
|
273
|
-
? __( 'Page' )
|
|
274
|
-
: __( 'Template' )
|
|
275
|
-
}
|
|
270
|
+
rootLabelText={ postTypeLabel }
|
|
276
271
|
/>
|
|
277
272
|
)
|
|
278
273
|
}
|
|
@@ -55,11 +55,21 @@ function FontLibraryProvider( { children } ) {
|
|
|
55
55
|
|
|
56
56
|
const [ isInstalling, setIsInstalling ] = useState( false );
|
|
57
57
|
const [ refreshKey, setRefreshKey ] = useState( 0 );
|
|
58
|
+
const [ notice, setNotice ] = useState( null );
|
|
58
59
|
|
|
59
60
|
const refreshLibrary = () => {
|
|
60
61
|
setRefreshKey( Date.now() );
|
|
61
62
|
};
|
|
62
63
|
|
|
64
|
+
// Reset notice on dismiss.
|
|
65
|
+
useEffect( () => {
|
|
66
|
+
if ( notice ) {
|
|
67
|
+
notice.onRemove = () => {
|
|
68
|
+
setNotice( null );
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}, [ notice, setNotice ] );
|
|
72
|
+
|
|
63
73
|
const {
|
|
64
74
|
records: libraryPosts = [],
|
|
65
75
|
isResolving: isResolvingLibrary,
|
|
@@ -134,6 +144,8 @@ function FontLibraryProvider( { children } ) {
|
|
|
134
144
|
}, [ modalTabOpen ] );
|
|
135
145
|
|
|
136
146
|
const handleSetLibraryFontSelected = ( font ) => {
|
|
147
|
+
setNotice( null );
|
|
148
|
+
|
|
137
149
|
// If font is null, reset the selected font
|
|
138
150
|
if ( ! font ) {
|
|
139
151
|
setLibraryFontSelected( null );
|
|
@@ -471,6 +483,8 @@ function FontLibraryProvider( { children } ) {
|
|
|
471
483
|
modalTabOpen,
|
|
472
484
|
toggleModal,
|
|
473
485
|
refreshLibrary,
|
|
486
|
+
notice,
|
|
487
|
+
setNotice,
|
|
474
488
|
saveFontFamilies,
|
|
475
489
|
fontFamiliesHasChanges,
|
|
476
490
|
isResolvingLibrary,
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
FlexItem,
|
|
13
13
|
Flex,
|
|
14
14
|
Button,
|
|
15
|
-
Notice,
|
|
16
15
|
} from '@wordpress/components';
|
|
17
16
|
import { debounce } from '@wordpress/compose';
|
|
18
17
|
import { __ } from '@wordpress/i18n';
|
|
@@ -30,31 +29,30 @@ import CollectionFontDetails from './collection-font-details';
|
|
|
30
29
|
import { toggleFont } from './utils/toggleFont';
|
|
31
30
|
import { getFontsOutline } from './utils/fonts-outline';
|
|
32
31
|
import GoogleFontsConfirmDialog from './google-fonts-confirm-dialog';
|
|
33
|
-
import {
|
|
32
|
+
import { downloadFontFaceAssets } from './utils';
|
|
34
33
|
|
|
35
34
|
const DEFAULT_CATEGORY = {
|
|
36
35
|
slug: 'all',
|
|
37
36
|
name: __( 'All' ),
|
|
38
37
|
};
|
|
39
38
|
function FontCollection( { slug } ) {
|
|
40
|
-
const requiresPermission = slug === '
|
|
39
|
+
const requiresPermission = slug === 'google-fonts';
|
|
41
40
|
|
|
42
41
|
const getGoogleFontsPermissionFromStorage = () => {
|
|
43
42
|
return (
|
|
44
43
|
window.localStorage.getItem(
|
|
45
|
-
'wp-font-library-
|
|
44
|
+
'wp-font-library-google-fonts-permission'
|
|
46
45
|
) === 'true'
|
|
47
46
|
);
|
|
48
47
|
};
|
|
49
48
|
|
|
50
|
-
const [ notice, setNotice ] = useState( null );
|
|
51
49
|
const [ selectedFont, setSelectedFont ] = useState( null );
|
|
52
50
|
const [ fontsToInstall, setFontsToInstall ] = useState( [] );
|
|
53
51
|
const [ filters, setFilters ] = useState( {} );
|
|
54
52
|
const [ renderConfirmDialog, setRenderConfirmDialog ] = useState(
|
|
55
53
|
requiresPermission && ! getGoogleFontsPermissionFromStorage()
|
|
56
54
|
);
|
|
57
|
-
const { collections, getFontCollection, installFont } =
|
|
55
|
+
const { collections, getFontCollection, installFont, notice, setNotice } =
|
|
58
56
|
useContext( FontLibraryContext );
|
|
59
57
|
const selectedCollection = collections.find(
|
|
60
58
|
( collection ) => collection.slug === slug
|
|
@@ -77,36 +75,27 @@ function FontCollection( { slug } ) {
|
|
|
77
75
|
await getFontCollection( slug );
|
|
78
76
|
resetFilters();
|
|
79
77
|
} catch ( e ) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
78
|
+
if ( ! notice ) {
|
|
79
|
+
setNotice( {
|
|
80
|
+
type: 'error',
|
|
81
|
+
message: e?.message,
|
|
82
|
+
} );
|
|
83
|
+
}
|
|
85
84
|
}
|
|
86
85
|
};
|
|
87
86
|
fetchFontCollection();
|
|
88
|
-
}, [ slug, getFontCollection ] );
|
|
87
|
+
}, [ slug, getFontCollection, setNotice, notice ] );
|
|
89
88
|
|
|
90
89
|
useEffect( () => {
|
|
91
90
|
setSelectedFont( null );
|
|
92
91
|
setNotice( null );
|
|
93
|
-
}, [ slug ] );
|
|
92
|
+
}, [ slug, setNotice ] );
|
|
94
93
|
|
|
95
94
|
useEffect( () => {
|
|
96
95
|
// If the selected fonts change, reset the selected fonts to install
|
|
97
96
|
setFontsToInstall( [] );
|
|
98
97
|
}, [ selectedFont ] );
|
|
99
98
|
|
|
100
|
-
// Reset notice after 5 seconds
|
|
101
|
-
useEffect( () => {
|
|
102
|
-
if ( notice && notice?.duration !== 0 ) {
|
|
103
|
-
const timeout = setTimeout( () => {
|
|
104
|
-
setNotice( null );
|
|
105
|
-
}, notice.duration ?? 5000 );
|
|
106
|
-
return () => clearTimeout( timeout );
|
|
107
|
-
}
|
|
108
|
-
}, [ notice ] );
|
|
109
|
-
|
|
110
99
|
const collectionFonts = useMemo(
|
|
111
100
|
() => selectedCollection?.font_families ?? [],
|
|
112
101
|
[ selectedCollection ]
|
|
@@ -154,6 +143,8 @@ function FontCollection( { slug } ) {
|
|
|
154
143
|
};
|
|
155
144
|
|
|
156
145
|
const handleInstall = async () => {
|
|
146
|
+
setNotice( null );
|
|
147
|
+
|
|
157
148
|
const fontFamily = fontsToInstall[ 0 ];
|
|
158
149
|
|
|
159
150
|
try {
|
|
@@ -161,7 +152,7 @@ function FontCollection( { slug } ) {
|
|
|
161
152
|
await Promise.all(
|
|
162
153
|
fontFamily.fontFace.map( async ( fontFace ) => {
|
|
163
154
|
if ( fontFace.src ) {
|
|
164
|
-
fontFace.file = await
|
|
155
|
+
fontFace.file = await downloadFontFaceAssets(
|
|
165
156
|
fontFace.src
|
|
166
157
|
);
|
|
167
158
|
}
|
|
@@ -205,6 +196,7 @@ function FontCollection( { slug } ) {
|
|
|
205
196
|
? selectedCollection.description
|
|
206
197
|
: __( 'Select font variants to install.' )
|
|
207
198
|
}
|
|
199
|
+
notice={ notice }
|
|
208
200
|
handleBack={ !! selectedFont && handleUnselectFont }
|
|
209
201
|
footer={
|
|
210
202
|
fontsToInstall.length > 0 && (
|
|
@@ -219,22 +211,6 @@ function FontCollection( { slug } ) {
|
|
|
219
211
|
</>
|
|
220
212
|
) }
|
|
221
213
|
|
|
222
|
-
{ notice && (
|
|
223
|
-
<>
|
|
224
|
-
<FlexItem>
|
|
225
|
-
<Spacer margin={ 2 } />
|
|
226
|
-
<Notice
|
|
227
|
-
isDismissible={ false }
|
|
228
|
-
status={ notice.type }
|
|
229
|
-
className="font-library-modal__font-collection__notice"
|
|
230
|
-
>
|
|
231
|
-
{ notice.message }
|
|
232
|
-
</Notice>
|
|
233
|
-
</FlexItem>
|
|
234
|
-
<Spacer margin={ 2 } />
|
|
235
|
-
</>
|
|
236
|
-
) }
|
|
237
|
-
|
|
238
214
|
{ ! renderConfirmDialog && ! selectedFont && (
|
|
239
215
|
<Flex>
|
|
240
216
|
<FlexItem>
|
|
@@ -62,7 +62,7 @@ function FontFaceDemo( { customPreviewUrl, fontFace, text, style = {} } ) {
|
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
64
|
loadAsset();
|
|
65
|
-
}, [ fontFace, isIntersecting, loadFontFaceAsset ] );
|
|
65
|
+
}, [ fontFace, isIntersecting, loadFontFaceAsset, isPreviewImage ] );
|
|
66
66
|
|
|
67
67
|
return (
|
|
68
68
|
<div ref={ ref }>
|
|
@@ -14,7 +14,7 @@ function GoogleFontsConfirmDialog() {
|
|
|
14
14
|
const handleConfirm = () => {
|
|
15
15
|
// eslint-disable-next-line no-undef
|
|
16
16
|
window.localStorage.setItem(
|
|
17
|
-
'wp-font-library-
|
|
17
|
+
'wp-font-library-google-fonts-permission',
|
|
18
18
|
'true'
|
|
19
19
|
);
|
|
20
20
|
window.dispatchEvent( new Event( 'storage' ) );
|
|
@@ -34,7 +34,7 @@ const tabsFromCollections = ( collections ) =>
|
|
|
34
34
|
collections.map( ( { slug, name } ) => ( {
|
|
35
35
|
id: slug,
|
|
36
36
|
title:
|
|
37
|
-
collections.length === 1 && slug === '
|
|
37
|
+
collections.length === 1 && slug === 'google-fonts'
|
|
38
38
|
? __( 'Install Fonts' )
|
|
39
39
|
: name,
|
|
40
40
|
} ) );
|
|
@@ -43,13 +43,18 @@ function FontLibraryModal( {
|
|
|
43
43
|
onRequestClose,
|
|
44
44
|
initialTabId = 'installed-fonts',
|
|
45
45
|
} ) {
|
|
46
|
-
const { collections } = useContext( FontLibraryContext );
|
|
46
|
+
const { collections, setNotice } = useContext( FontLibraryContext );
|
|
47
47
|
|
|
48
48
|
const tabs = [
|
|
49
49
|
...DEFAULT_TABS,
|
|
50
50
|
...tabsFromCollections( collections || [] ),
|
|
51
51
|
];
|
|
52
52
|
|
|
53
|
+
// Reset notice when new tab is selected.
|
|
54
|
+
const onSelect = () => {
|
|
55
|
+
setNotice( null );
|
|
56
|
+
};
|
|
57
|
+
|
|
53
58
|
return (
|
|
54
59
|
<Modal
|
|
55
60
|
title={ __( 'Fonts' ) }
|
|
@@ -58,7 +63,7 @@ function FontLibraryModal( {
|
|
|
58
63
|
className="font-library-modal"
|
|
59
64
|
>
|
|
60
65
|
<div className="font-library-modal__tabs">
|
|
61
|
-
<Tabs initialTabId={ initialTabId }>
|
|
66
|
+
<Tabs initialTabId={ initialTabId } onSelect={ onSelect }>
|
|
62
67
|
<Tabs.TabList>
|
|
63
68
|
{ tabs.map( ( { id, title } ) => (
|
|
64
69
|
<Tabs.Tab key={ id } tabId={ id }>
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
__experimentalSpacer as Spacer,
|
|
10
10
|
Button,
|
|
11
11
|
Spinner,
|
|
12
|
-
Notice,
|
|
13
12
|
FlexItem,
|
|
14
13
|
} from '@wordpress/components';
|
|
15
14
|
|
|
@@ -34,6 +33,8 @@ function InstalledFonts() {
|
|
|
34
33
|
refreshLibrary,
|
|
35
34
|
uninstallFontFamily,
|
|
36
35
|
isResolvingLibrary,
|
|
36
|
+
notice,
|
|
37
|
+
setNotice,
|
|
37
38
|
} = useContext( FontLibraryContext );
|
|
38
39
|
const [ isConfirmDeleteOpen, setIsConfirmDeleteOpen ] = useState( false );
|
|
39
40
|
|
|
@@ -45,9 +46,9 @@ function InstalledFonts() {
|
|
|
45
46
|
handleSetLibraryFontSelected( font );
|
|
46
47
|
};
|
|
47
48
|
|
|
48
|
-
const [ notice, setNotice ] = useState( null );
|
|
49
|
-
|
|
50
49
|
const handleConfirmUninstall = async () => {
|
|
50
|
+
setNotice( null );
|
|
51
|
+
|
|
51
52
|
try {
|
|
52
53
|
await uninstallFontFamily( libraryFontSelected );
|
|
53
54
|
setNotice( {
|
|
@@ -91,20 +92,11 @@ function InstalledFonts() {
|
|
|
91
92
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
92
93
|
}, [] );
|
|
93
94
|
|
|
94
|
-
// Reset notice after 5 seconds
|
|
95
|
-
useEffect( () => {
|
|
96
|
-
if ( notice ) {
|
|
97
|
-
const timeout = setTimeout( () => {
|
|
98
|
-
setNotice( null );
|
|
99
|
-
}, 5000 );
|
|
100
|
-
return () => clearTimeout( timeout );
|
|
101
|
-
}
|
|
102
|
-
}, [ notice ] );
|
|
103
|
-
|
|
104
95
|
return (
|
|
105
96
|
<TabPanelLayout
|
|
106
97
|
title={ libraryFontSelected?.name || '' }
|
|
107
98
|
description={ tabDescription }
|
|
99
|
+
notice={ notice }
|
|
108
100
|
handleBack={ !! libraryFontSelected && handleUnselectFont }
|
|
109
101
|
footer={
|
|
110
102
|
<Footer
|
|
@@ -120,28 +112,17 @@ function InstalledFonts() {
|
|
|
120
112
|
handleCancelUninstall={ handleCancelUninstall }
|
|
121
113
|
/>
|
|
122
114
|
|
|
123
|
-
{ notice && (
|
|
124
|
-
<>
|
|
125
|
-
<FlexItem>
|
|
126
|
-
<Spacer margin={ 2 } />
|
|
127
|
-
<Notice
|
|
128
|
-
isDismissible={ false }
|
|
129
|
-
status={ notice.type }
|
|
130
|
-
className="font-library-modal__font-collection__notice"
|
|
131
|
-
>
|
|
132
|
-
{ notice.message }
|
|
133
|
-
</Notice>
|
|
134
|
-
</FlexItem>
|
|
135
|
-
<Spacer margin={ 4 } />
|
|
136
|
-
</>
|
|
137
|
-
) }
|
|
138
|
-
|
|
139
115
|
{ ! libraryFontSelected && (
|
|
140
116
|
<>
|
|
141
|
-
{ isResolvingLibrary &&
|
|
117
|
+
{ isResolvingLibrary && (
|
|
118
|
+
<FlexItem>
|
|
119
|
+
<Spacer margin={ 2 } />
|
|
120
|
+
<Spinner />
|
|
121
|
+
<Spacer margin={ 2 } />
|
|
122
|
+
</FlexItem>
|
|
123
|
+
) }
|
|
142
124
|
{ baseCustomFonts.length > 0 && (
|
|
143
125
|
<>
|
|
144
|
-
<Spacer margin={ 2 } />
|
|
145
126
|
<FontsGrid>
|
|
146
127
|
{ baseCustomFonts.map( ( font ) => (
|
|
147
128
|
<LibraryFontCard
|
|
@@ -20,7 +20,7 @@ function LibraryFontVariant( { face, font } ) {
|
|
|
20
20
|
const { isFontActivated, toggleActivateFont } =
|
|
21
21
|
useContext( FontLibraryContext );
|
|
22
22
|
|
|
23
|
-
const
|
|
23
|
+
const isInstalled =
|
|
24
24
|
font?.fontFace?.length > 0
|
|
25
25
|
? isFontActivated(
|
|
26
26
|
font.slug,
|
|
@@ -52,7 +52,7 @@ function LibraryFontVariant( { face, font } ) {
|
|
|
52
52
|
<Flex justify="space-between" align="center" gap="1rem">
|
|
53
53
|
<FontFaceDemo fontFace={ face } text={ displayName } />
|
|
54
54
|
<CheckboxControl
|
|
55
|
-
checked={
|
|
55
|
+
checked={ isInstalled }
|
|
56
56
|
onChange={ handleToggleActivation }
|
|
57
57
|
__nextHasNoMarginBottom={ true }
|
|
58
58
|
id={ checkboxId }
|
|
@@ -63,7 +63,7 @@ export async function fetchUninstallFontFamily( fontFamilyId ) {
|
|
|
63
63
|
|
|
64
64
|
export async function fetchFontCollections() {
|
|
65
65
|
const config = {
|
|
66
|
-
path: FONT_COLLECTIONS_URL,
|
|
66
|
+
path: `${ FONT_COLLECTIONS_URL }?_fields=slug,name,description`,
|
|
67
67
|
method: 'GET',
|
|
68
68
|
};
|
|
69
69
|
return await apiFetch( config );
|
|
@@ -25,11 +25,6 @@
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
.font-library-modal__tabpanel-layout {
|
|
28
|
-
|
|
29
|
-
.font-library-modal__tabpanel-layout__main {
|
|
30
|
-
padding-bottom: $grid-unit-80;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
28
|
.font-library-modal__tabpanel-layout__footer {
|
|
34
29
|
border-top: 1px solid $gray-300;
|
|
35
30
|
margin: 0 #{$grid-unit-40 * -1} #{$grid-unit-40 * -1};
|
|
@@ -39,7 +34,6 @@
|
|
|
39
34
|
width: 100%;
|
|
40
35
|
background-color: $white;
|
|
41
36
|
}
|
|
42
|
-
|
|
43
37
|
}
|
|
44
38
|
|
|
45
39
|
.font-library-modal__fonts-grid {
|
|
@@ -107,10 +101,6 @@ button.font-library-modal__upload-area {
|
|
|
107
101
|
.font-library-modal__upload-area__text {
|
|
108
102
|
color: $gray-700;
|
|
109
103
|
}
|
|
110
|
-
|
|
111
|
-
.font-library-modal__upload-area__notice {
|
|
112
|
-
margin: 0;
|
|
113
|
-
}
|
|
114
104
|
}
|
|
115
105
|
|
|
116
106
|
.font-library-modal__font-variant_demo-wrapper {
|
|
@@ -8,12 +8,15 @@ import {
|
|
|
8
8
|
__experimentalSpacer as Spacer,
|
|
9
9
|
__experimentalHStack as HStack,
|
|
10
10
|
Button,
|
|
11
|
+
Notice,
|
|
12
|
+
FlexBlock,
|
|
11
13
|
} from '@wordpress/components';
|
|
12
14
|
import { chevronLeft } from '@wordpress/icons';
|
|
13
15
|
|
|
14
16
|
function TabPanelLayout( {
|
|
15
17
|
title,
|
|
16
18
|
description,
|
|
19
|
+
notice,
|
|
17
20
|
handleBack,
|
|
18
21
|
children,
|
|
19
22
|
footer,
|
|
@@ -43,6 +46,18 @@ function TabPanelLayout( {
|
|
|
43
46
|
) }
|
|
44
47
|
</HStack>
|
|
45
48
|
{ description && <Text>{ description }</Text> }
|
|
49
|
+
{ notice && (
|
|
50
|
+
<FlexBlock>
|
|
51
|
+
<Spacer margin={ 1 } />
|
|
52
|
+
<Notice
|
|
53
|
+
status={ notice.type }
|
|
54
|
+
onRemove={ notice.onRemove }
|
|
55
|
+
>
|
|
56
|
+
{ notice.message }
|
|
57
|
+
</Notice>
|
|
58
|
+
<Spacer margin={ 1 } />
|
|
59
|
+
</FlexBlock>
|
|
60
|
+
) }
|
|
46
61
|
</VStack>
|
|
47
62
|
<div className="font-library-modal__tabpanel-layout__main">
|
|
48
63
|
{ children }
|
|
@@ -1,19 +1,214 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { __, sprintf } from '@wordpress/i18n';
|
|
5
|
+
import {
|
|
6
|
+
Button,
|
|
7
|
+
DropZone,
|
|
8
|
+
__experimentalSpacer as Spacer,
|
|
9
|
+
__experimentalText as Text,
|
|
10
|
+
__experimentalVStack as VStack,
|
|
11
|
+
FormFileUpload,
|
|
12
|
+
FlexItem,
|
|
13
|
+
privateApis as componentsPrivateApis,
|
|
14
|
+
} from '@wordpress/components';
|
|
15
|
+
import { useContext, useState } from '@wordpress/element';
|
|
5
16
|
|
|
6
17
|
/**
|
|
7
18
|
* Internal dependencies
|
|
8
19
|
*/
|
|
9
|
-
import
|
|
20
|
+
import { ALLOWED_FILE_EXTENSIONS } from './utils/constants';
|
|
21
|
+
import { FontLibraryContext } from './context';
|
|
22
|
+
import { Font } from '../../../../lib/lib-font.browser';
|
|
23
|
+
import makeFamiliesFromFaces from './utils/make-families-from-faces';
|
|
24
|
+
import { loadFontFaceInBrowser } from './utils';
|
|
25
|
+
import TabPanelLayout from './tab-panel-layout';
|
|
26
|
+
import { unlock } from '../../../lock-unlock';
|
|
27
|
+
|
|
28
|
+
const { ProgressBar } = unlock( componentsPrivateApis );
|
|
10
29
|
|
|
11
30
|
function UploadFonts() {
|
|
31
|
+
const { installFont, notice, setNotice } = useContext( FontLibraryContext );
|
|
32
|
+
const [ isUploading, setIsUploading ] = useState( false );
|
|
33
|
+
const supportedFormats =
|
|
34
|
+
ALLOWED_FILE_EXTENSIONS.slice( 0, -1 )
|
|
35
|
+
.map( ( extension ) => `.${ extension }` )
|
|
36
|
+
.join( ', ' ) +
|
|
37
|
+
` ${ __( 'and' ) } .${ ALLOWED_FILE_EXTENSIONS.slice( -1 ) }`;
|
|
38
|
+
|
|
39
|
+
const handleDropZone = ( files ) => {
|
|
40
|
+
handleFilesUpload( files );
|
|
41
|
+
};
|
|
42
|
+
const onFilesUpload = ( event ) => {
|
|
43
|
+
handleFilesUpload( event.target.files );
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Filters the selected files to only allow the ones with the allowed extensions
|
|
48
|
+
*
|
|
49
|
+
* @param {Array} files The files to be filtered
|
|
50
|
+
* @return {void}
|
|
51
|
+
*/
|
|
52
|
+
const handleFilesUpload = ( files ) => {
|
|
53
|
+
setNotice( null );
|
|
54
|
+
setIsUploading( true );
|
|
55
|
+
const uniqueFilenames = new Set();
|
|
56
|
+
const selectedFiles = [ ...files ];
|
|
57
|
+
const allowedFiles = selectedFiles.filter( ( file ) => {
|
|
58
|
+
if ( uniqueFilenames.has( file.name ) ) {
|
|
59
|
+
return false; // Discard duplicates
|
|
60
|
+
}
|
|
61
|
+
// Eliminates files that are not allowed
|
|
62
|
+
const fileExtension = file.name.split( '.' ).pop().toLowerCase();
|
|
63
|
+
if ( ALLOWED_FILE_EXTENSIONS.includes( fileExtension ) ) {
|
|
64
|
+
uniqueFilenames.add( file.name );
|
|
65
|
+
return true; // Keep file if the extension is allowed
|
|
66
|
+
}
|
|
67
|
+
return false; // Discard file extension not allowed
|
|
68
|
+
} );
|
|
69
|
+
if ( allowedFiles.length > 0 ) {
|
|
70
|
+
loadFiles( allowedFiles );
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Loads the selected files and reads the font metadata
|
|
76
|
+
*
|
|
77
|
+
* @param {Array} files The files to be loaded
|
|
78
|
+
* @return {void}
|
|
79
|
+
*/
|
|
80
|
+
const loadFiles = async ( files ) => {
|
|
81
|
+
const fontFacesLoaded = await Promise.all(
|
|
82
|
+
files.map( async ( fontFile ) => {
|
|
83
|
+
const fontFaceData = await getFontFaceMetadata( fontFile );
|
|
84
|
+
await loadFontFaceInBrowser(
|
|
85
|
+
fontFaceData,
|
|
86
|
+
fontFaceData.file,
|
|
87
|
+
'all'
|
|
88
|
+
);
|
|
89
|
+
return fontFaceData;
|
|
90
|
+
} )
|
|
91
|
+
);
|
|
92
|
+
handleInstall( fontFacesLoaded );
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// Create a function to read the file as array buffer
|
|
96
|
+
async function readFileAsArrayBuffer( file ) {
|
|
97
|
+
return new Promise( ( resolve, reject ) => {
|
|
98
|
+
const reader = new window.FileReader();
|
|
99
|
+
reader.readAsArrayBuffer( file );
|
|
100
|
+
reader.onload = () => resolve( reader.result );
|
|
101
|
+
reader.onerror = reject;
|
|
102
|
+
} );
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const getFontFaceMetadata = async ( fontFile ) => {
|
|
106
|
+
const buffer = await readFileAsArrayBuffer( fontFile );
|
|
107
|
+
const fontObj = new Font( 'Uploaded Font' );
|
|
108
|
+
fontObj.fromDataBuffer( buffer, fontFile.name );
|
|
109
|
+
// Assuming that fromDataBuffer triggers onload event and returning a Promise
|
|
110
|
+
const onloadEvent = await new Promise(
|
|
111
|
+
( resolve ) => ( fontObj.onload = resolve )
|
|
112
|
+
);
|
|
113
|
+
const font = onloadEvent.detail.font;
|
|
114
|
+
const { name } = font.opentype.tables;
|
|
115
|
+
const fontName = name.get( 16 ) || name.get( 1 );
|
|
116
|
+
const isItalic = name.get( 2 ).toLowerCase().includes( 'italic' );
|
|
117
|
+
const fontWeight =
|
|
118
|
+
font.opentype.tables[ 'OS/2' ].usWeightClass || 'normal';
|
|
119
|
+
const isVariable = !! font.opentype.tables.fvar;
|
|
120
|
+
const weightAxis =
|
|
121
|
+
isVariable &&
|
|
122
|
+
font.opentype.tables.fvar.axes.find(
|
|
123
|
+
( { tag } ) => tag === 'wght'
|
|
124
|
+
);
|
|
125
|
+
const weightRange = weightAxis
|
|
126
|
+
? `${ weightAxis.minValue } ${ weightAxis.maxValue }`
|
|
127
|
+
: null;
|
|
128
|
+
return {
|
|
129
|
+
file: fontFile,
|
|
130
|
+
fontFamily: fontName,
|
|
131
|
+
fontStyle: isItalic ? 'italic' : 'normal',
|
|
132
|
+
fontWeight: weightRange || fontWeight,
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Creates the font family definition and sends it to the server
|
|
138
|
+
*
|
|
139
|
+
* @param {Array} fontFaces The font faces to be installed
|
|
140
|
+
* @return {void}
|
|
141
|
+
*/
|
|
142
|
+
const handleInstall = async ( fontFaces ) => {
|
|
143
|
+
const fontFamilies = makeFamiliesFromFaces( fontFaces );
|
|
144
|
+
|
|
145
|
+
if ( fontFamilies.length > 1 ) {
|
|
146
|
+
setNotice( {
|
|
147
|
+
type: 'error',
|
|
148
|
+
message: __(
|
|
149
|
+
'Variants from only one font family can be uploaded at a time.'
|
|
150
|
+
),
|
|
151
|
+
} );
|
|
152
|
+
setIsUploading( false );
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
await installFont( fontFamilies[ 0 ] );
|
|
158
|
+
setNotice( {
|
|
159
|
+
type: 'success',
|
|
160
|
+
message: __( 'Fonts were installed successfully.' ),
|
|
161
|
+
} );
|
|
162
|
+
} catch ( error ) {
|
|
163
|
+
setNotice( {
|
|
164
|
+
type: 'error',
|
|
165
|
+
message: error.message,
|
|
166
|
+
} );
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
setIsUploading( false );
|
|
170
|
+
};
|
|
171
|
+
|
|
12
172
|
return (
|
|
13
|
-
|
|
14
|
-
<
|
|
15
|
-
<
|
|
16
|
-
|
|
173
|
+
<TabPanelLayout notice={ notice }>
|
|
174
|
+
<DropZone onFilesDrop={ handleDropZone } />
|
|
175
|
+
<VStack className="font-library-modal__local-fonts">
|
|
176
|
+
{ isUploading && (
|
|
177
|
+
<FlexItem>
|
|
178
|
+
<div className="font-library-modal__upload-area">
|
|
179
|
+
<ProgressBar />
|
|
180
|
+
</div>
|
|
181
|
+
</FlexItem>
|
|
182
|
+
) }
|
|
183
|
+
{ ! isUploading && (
|
|
184
|
+
<FormFileUpload
|
|
185
|
+
accept={ ALLOWED_FILE_EXTENSIONS.map(
|
|
186
|
+
( ext ) => `.${ ext }`
|
|
187
|
+
).join( ',' ) }
|
|
188
|
+
multiple={ true }
|
|
189
|
+
onChange={ onFilesUpload }
|
|
190
|
+
render={ ( { openFileDialog } ) => (
|
|
191
|
+
<Button
|
|
192
|
+
className="font-library-modal__upload-area"
|
|
193
|
+
onClick={ openFileDialog }
|
|
194
|
+
>
|
|
195
|
+
<span>{ __( 'Upload font' ) }</span>
|
|
196
|
+
</Button>
|
|
197
|
+
) }
|
|
198
|
+
/>
|
|
199
|
+
) }
|
|
200
|
+
<Spacer margin={ 2 } />
|
|
201
|
+
<Text className="font-library-modal__upload-area__text">
|
|
202
|
+
{ sprintf(
|
|
203
|
+
/* translators: %s: supported font formats: ex: .ttf, .woff and .woff2 */
|
|
204
|
+
__(
|
|
205
|
+
'Uploaded fonts appear in your library and can be used in your theme. Supported formats: %s.'
|
|
206
|
+
),
|
|
207
|
+
supportedFormats
|
|
208
|
+
) }
|
|
209
|
+
</Text>
|
|
210
|
+
</VStack>
|
|
211
|
+
</TabPanelLayout>
|
|
17
212
|
);
|
|
18
213
|
}
|
|
19
214
|
|