@secretstache/wordpress-gutenberg 0.5.0 → 0.5.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/README.md +13 -3
- package/build/index.js +3 -3
- package/build/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.d.ts +152 -0
- package/src/utils/constants.js +0 -6
- package/src/utils/helpers.js +93 -4
package/package.json
CHANGED
package/src/index.d.ts
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
declare module '@secretstache/wordpress-gutenberg' {
|
2
|
+
import { ReactNode, FC } from 'react';
|
3
|
+
import { BlockInstance } from '@wordpress/blocks';
|
4
|
+
|
5
|
+
// Constants
|
6
|
+
export const MEDIA_TYPE: {
|
7
|
+
IMAGE: 'image';
|
8
|
+
VIDEO: 'video';
|
9
|
+
ANIMATION: 'animation';
|
10
|
+
};
|
11
|
+
|
12
|
+
// Components
|
13
|
+
export interface ColorPaletteControlProps {
|
14
|
+
label?: string;
|
15
|
+
value: string;
|
16
|
+
attributeName: string;
|
17
|
+
setAttributes: (attrs: any) => void;
|
18
|
+
allowedColors?: string[];
|
19
|
+
}
|
20
|
+
export const ColorPaletteControl: FC<ColorPaletteControlProps>;
|
21
|
+
|
22
|
+
export interface MediaControlProps {
|
23
|
+
mediaId: number;
|
24
|
+
mediaUrl: string;
|
25
|
+
mediaFileName?: string;
|
26
|
+
onSelect: (media: any) => void;
|
27
|
+
onRemove: () => void;
|
28
|
+
type?: 'image' | 'video' | 'animation';
|
29
|
+
selectButtonLabel?: string;
|
30
|
+
removeButtonLabel?: string;
|
31
|
+
}
|
32
|
+
export const MediaControl: FC<MediaControlProps>;
|
33
|
+
|
34
|
+
export interface PreviewControlProps {
|
35
|
+
checked: boolean;
|
36
|
+
onChange: (value: boolean) => void;
|
37
|
+
help?: string;
|
38
|
+
label?: string;
|
39
|
+
}
|
40
|
+
export const PreviewControl: FC<PreviewControlProps>;
|
41
|
+
|
42
|
+
export interface ResourcesWrapperProps {
|
43
|
+
isLoading?: boolean;
|
44
|
+
isEmptyResources?: boolean;
|
45
|
+
isEmptySelection?: boolean;
|
46
|
+
isPlaceholder?: boolean;
|
47
|
+
emptyResourcesMessage?: string;
|
48
|
+
emptySelectionMessage?: string;
|
49
|
+
placeholderProps?: {
|
50
|
+
icon?: string;
|
51
|
+
instructions?: string;
|
52
|
+
[key: string]: any;
|
53
|
+
};
|
54
|
+
children?: ReactNode;
|
55
|
+
}
|
56
|
+
export const ResourcesWrapper: FC<ResourcesWrapperProps>;
|
57
|
+
|
58
|
+
export interface DataQueryControlsProps {
|
59
|
+
dataSourceLabel?: string;
|
60
|
+
dataSource: string;
|
61
|
+
onDataSourceChange: (value: string) => void;
|
62
|
+
queryTypeLabel?: string;
|
63
|
+
queryType: string;
|
64
|
+
onQueryTypeChange: (value: string) => void;
|
65
|
+
settings: Array<{
|
66
|
+
value: string;
|
67
|
+
label: string;
|
68
|
+
queries?: Array<{
|
69
|
+
value: string;
|
70
|
+
label: string;
|
71
|
+
}>;
|
72
|
+
}>;
|
73
|
+
}
|
74
|
+
export const DataQueryControls: FC<DataQueryControlsProps>;
|
75
|
+
|
76
|
+
// Hooks
|
77
|
+
export function usePreviewControl(): {
|
78
|
+
isPreview: boolean;
|
79
|
+
setIsPreview: (value: boolean) => void;
|
80
|
+
PreviewControl: FC<PreviewControlProps>;
|
81
|
+
};
|
82
|
+
|
83
|
+
export function useThemeColors(allowedColors?: string[]): Array<{
|
84
|
+
name: string;
|
85
|
+
slug: string;
|
86
|
+
color: string;
|
87
|
+
}>;
|
88
|
+
|
89
|
+
export function useColorChange(
|
90
|
+
colors: Array<{ color: string; slug: string }>,
|
91
|
+
setAttributes: (attrs: any) => void
|
92
|
+
): (colorValue: string, property: string) => void;
|
93
|
+
|
94
|
+
export function useDataQuery(config: {
|
95
|
+
postType: string | (() => string);
|
96
|
+
curatedPostsIds?: number[];
|
97
|
+
taxonomySlug?: string;
|
98
|
+
curatedTermsIds?: number[];
|
99
|
+
numberOfPosts?: number;
|
100
|
+
extraQueryArgs?: Record<string, any>;
|
101
|
+
}, dependencies?: any[]): {
|
102
|
+
postsToShow: any[];
|
103
|
+
isResolving: boolean;
|
104
|
+
isEmpty: boolean;
|
105
|
+
};
|
106
|
+
|
107
|
+
export function useParentBlock(
|
108
|
+
parentBlockName: string,
|
109
|
+
blockClientIdToLimitSearch?: string
|
110
|
+
): BlockInstance | null;
|
111
|
+
|
112
|
+
export function useSlider(
|
113
|
+
isEnabled: boolean,
|
114
|
+
setupSlider: (element: HTMLElement) => any,
|
115
|
+
cleanCallback?: () => void,
|
116
|
+
dependencies?: any[]
|
117
|
+
): {
|
118
|
+
sliderElRef: React.RefObject<HTMLElement>;
|
119
|
+
sliderInstance: React.RefObject<any>;
|
120
|
+
};
|
121
|
+
|
122
|
+
export function useAccordionItem(
|
123
|
+
itemId: string,
|
124
|
+
activeItemId: string | null,
|
125
|
+
setActiveItemId: (id: string | null) => void,
|
126
|
+
contentSelector: string,
|
127
|
+
heightObserverDeps?: any[]
|
128
|
+
): {
|
129
|
+
blockRef: React.RefObject<HTMLElement>;
|
130
|
+
toggleItem: () => void;
|
131
|
+
openContent: () => void;
|
132
|
+
closeContent: () => void;
|
133
|
+
isActive: boolean;
|
134
|
+
};
|
135
|
+
|
136
|
+
export function useAllowedBlocks(
|
137
|
+
blockName: string,
|
138
|
+
excludedBlocks?: string[]
|
139
|
+
): string[];
|
140
|
+
|
141
|
+
export function useChildBlockPosition(
|
142
|
+
childClientId: string
|
143
|
+
): {
|
144
|
+
block: BlockInstance | null;
|
145
|
+
parentBlock: BlockInstance | null;
|
146
|
+
position: number;
|
147
|
+
};
|
148
|
+
|
149
|
+
export function useFilterBlocks(
|
150
|
+
filter: (block: BlockInstance) => boolean
|
151
|
+
): string[];
|
152
|
+
}
|
package/src/utils/constants.js
CHANGED
package/src/utils/helpers.js
CHANGED
@@ -2,7 +2,17 @@ import { filters } from '@wordpress/hooks';
|
|
2
2
|
import apiFetch from '@wordpress/api-fetch';
|
3
3
|
import slugify from 'slugify';
|
4
4
|
import classNames from 'classnames';
|
5
|
+
import { select, subscribe } from '@wordpress/data';
|
6
|
+
import { getBlockType, registerBlockType, unregisterBlockType } from '@wordpress/blocks';
|
5
7
|
|
8
|
+
/**
|
9
|
+
* Loads select options by fetching posts from WordPress REST API.
|
10
|
+
* @async
|
11
|
+
* @param {string} inputValue - Search term to filter posts
|
12
|
+
* @param {string} postType - WordPress post type to query
|
13
|
+
* @param {Function|null} [mapper=null] - Optional function to transform API response items
|
14
|
+
* @returns {Promise<Array<{value: number, label: string}>>} Array of select options
|
15
|
+
*/
|
6
16
|
export const loadSelectOptions = async (inputValue, postType, mapper = null) => {
|
7
17
|
const response = await apiFetch({
|
8
18
|
path: `/wp/v2/${postType}?search=${encodeURIComponent(inputValue)}`,
|
@@ -24,12 +34,22 @@ export const loadSelectOptions = async (inputValue, postType, mapper = null) =>
|
|
24
34
|
}
|
25
35
|
};
|
26
36
|
|
37
|
+
/**
|
38
|
+
* Converts a string to a URL-friendly slug.
|
39
|
+
* @param {string} name - String to convert to slug
|
40
|
+
* @returns {string} URL-friendly slug in lowercase with hyphens
|
41
|
+
*/
|
27
42
|
export const getSlug = (name) => slugify(name, {
|
28
43
|
replacement: '-',
|
29
44
|
lower: true,
|
30
45
|
strict: true,
|
31
46
|
});
|
32
47
|
|
48
|
+
/**
|
49
|
+
* Cleans SVG string by removing XML declaration and extra whitespace.
|
50
|
+
* @param {string} svgString - Raw SVG string
|
51
|
+
* @returns {string} Cleaned SVG string
|
52
|
+
*/
|
33
53
|
export const cleanSvgString = (svgString) => {
|
34
54
|
if (svgString.startsWith('<?xml')) {
|
35
55
|
const endOfXml = svgString.indexOf('?>');
|
@@ -44,9 +64,20 @@ export const cleanSvgString = (svgString) => {
|
|
44
64
|
return svgString;
|
45
65
|
};
|
46
66
|
|
47
|
-
|
48
|
-
|
67
|
+
/**
|
68
|
+
* Fetches and processes image data, handling both SVG and regular images.
|
69
|
+
* @async
|
70
|
+
* @param {Object} mediaData - WordPress media object
|
71
|
+
* @param {string} mediaData.mime - Media MIME type
|
72
|
+
* @param {string} mediaData.mime_type - Alternative MIME type property
|
73
|
+
* @param {string} mediaData.url - Media URL
|
74
|
+
* @param {number} mediaData.width - Image width
|
75
|
+
* @param {number} mediaData.height - Image height
|
76
|
+
* @returns {Promise<{isSvg: boolean, imageUrl: string|null, svgCode: string|null, width: number, height: number}>}
|
77
|
+
*/
|
49
78
|
export const getImage = async (mediaData) => {
|
79
|
+
const SVG_MIME_TYPE = 'image/svg+xml';
|
80
|
+
|
50
81
|
const isSvg = mediaData?.mime === SVG_MIME_TYPE || mediaData?.mime_type === SVG_MIME_TYPE;
|
51
82
|
const imagePayload = {
|
52
83
|
isSvg,
|
@@ -65,6 +96,11 @@ export const getImage = async (mediaData) => {
|
|
65
96
|
return imagePayload;
|
66
97
|
};
|
67
98
|
|
99
|
+
/**
|
100
|
+
* Formats a phone number string into XXX-XXX-XXXX format.
|
101
|
+
* @param {string} phone - Phone number starting with '+1' followed by 10 digits
|
102
|
+
* @returns {string} Formatted phone number or empty string if invalid
|
103
|
+
*/
|
68
104
|
export const getPhoneNumber = (phone) => {
|
69
105
|
if (!phone) return '';
|
70
106
|
|
@@ -80,6 +116,16 @@ export const getPhoneNumber = (phone) => {
|
|
80
116
|
return formatted;
|
81
117
|
};
|
82
118
|
|
119
|
+
/**
|
120
|
+
* Generates a formatted address string from location components.
|
121
|
+
* @param {Object} location - Location object
|
122
|
+
* @param {string} [location.street_number] - Street number
|
123
|
+
* @param {string} [location.street_name] - Street name
|
124
|
+
* @param {string} [location.city] - City
|
125
|
+
* @param {string} [location.state_short] - State abbreviation
|
126
|
+
* @param {string} [location.post_code] - Postal code
|
127
|
+
* @returns {string} Formatted address with HTML line breaks
|
128
|
+
*/
|
83
129
|
export const getLocationAddress = (location) => {
|
84
130
|
const {
|
85
131
|
street_number = '',
|
@@ -111,6 +157,11 @@ export const getLocationAddress = (location) => {
|
|
111
157
|
return addressParts.join('');
|
112
158
|
};
|
113
159
|
|
160
|
+
/**
|
161
|
+
* Decodes HTML entities to their corresponding characters.
|
162
|
+
* @param {string} text - Text containing HTML entities
|
163
|
+
* @returns {string} Decoded text
|
164
|
+
*/
|
114
165
|
export const decodeHtmlEntities = (text) => {
|
115
166
|
const tempElement = document.createElement('div');
|
116
167
|
tempElement.innerHTML = text;
|
@@ -147,8 +198,9 @@ export const getSpacingClasses = (
|
|
147
198
|
};
|
148
199
|
|
149
200
|
/**
|
150
|
-
*
|
151
|
-
* @
|
201
|
+
* Retrieves WordPress filters by namespace.
|
202
|
+
* @param {string} namespace - Filter namespace to search for
|
203
|
+
* @returns {Array<{filterName: string, namespace: string}>} Array of matching filters
|
152
204
|
*/
|
153
205
|
const getFiltersByNamespace = (namespace) => {
|
154
206
|
const list = [];
|
@@ -165,3 +217,40 @@ const getFiltersByNamespace = (namespace) => {
|
|
165
217
|
|
166
218
|
return list;
|
167
219
|
};
|
220
|
+
|
221
|
+
/**
|
222
|
+
* Unregisters a block type for a specific post type when editor loads.
|
223
|
+
* @param {string} blockName - Name of the block to unregister
|
224
|
+
* @param {string} postType - Post type to check against
|
225
|
+
*/
|
226
|
+
const unsetBlockForPostType = (blockName, postType) => {
|
227
|
+
const unsubscribe = subscribe(
|
228
|
+
() => {
|
229
|
+
const currentPostType = select('core/editor').getCurrentPostType();
|
230
|
+
if (currentPostType === postType && getBlockType(blockName)) {
|
231
|
+
unregisterBlockType(blockName);
|
232
|
+
unsubscribe();
|
233
|
+
}
|
234
|
+
},
|
235
|
+
'core/editor'
|
236
|
+
);
|
237
|
+
};
|
238
|
+
|
239
|
+
/**
|
240
|
+
* Update the API version of a specific block.
|
241
|
+
*
|
242
|
+
* @param {string} blockName - The name of the block to update (e.g., 'gravityforms/form').
|
243
|
+
* @param {number} [apiVersion=3] - The API version to set for the block. Defaults to 3.
|
244
|
+
*/
|
245
|
+
export function updateBlockApiVersion(blockName, apiVersion = 3) {
|
246
|
+
const blockSettings = getBlockType(blockName);
|
247
|
+
|
248
|
+
if (blockSettings) {
|
249
|
+
unregisterBlockType(blockName);
|
250
|
+
|
251
|
+
registerBlockType(blockName, {
|
252
|
+
...blockSettings,
|
253
|
+
apiVersion,
|
254
|
+
});
|
255
|
+
}
|
256
|
+
}
|