@secretstache/wordpress-gutenberg 0.5.0 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@secretstache/wordpress-gutenberg",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "",
5
5
  "author": "Secret Stache",
6
6
  "license": "GPL-2.0-or-later",
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
+ }
@@ -1,9 +1,3 @@
1
- export const QUERY_TYPE = {
2
- LATEST: 'latest',
3
- CURATED: 'curated',
4
- BY_CATEGORY: 'by_category'
5
- };
6
-
7
1
  export const MEDIA_TYPE = {
8
2
  IMAGE: 'image',
9
3
  VIDEO: 'video',
@@ -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
- const SVG_MIME_TYPE = 'image/svg+xml';
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
- * @param namespace
151
- * @returns {*[]}
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
+ }