import apiFetch from '@wordpress/api-fetch'; import { select } from '@wordpress/data'; import has from 'lodash/has'; import type { DesignTokenProp } from '@components/Settings/DesignToken/DesignTokenModal'; export const safeWpData = (): any => { if (has(window, 'parent.wp.data')) { // @ts-ignore return window.parent.wp.data; } else if (has(window, 'wp.data')) { return wp.data; } else { return null; } }; /* * This function is used to check if the current post is saving * @param {Object} * @returns {Boolean} * @example * isSaving({ wp }) * // returns true or false * */ blockbite.getSaveState = () => { const { __experimentalGetDirtyEntityRecords, isSavingEntityRecord } = select('core'); const dirtyEntityRecords = __experimentalGetDirtyEntityRecords(); const isSaving = dirtyEntityRecords.some((record: any) => isSavingEntityRecord(record.kind, record.name, record.key) ); return isSaving; }; /* * This function is used to check if the current post is saving * @param {Object} * @returns {Boolean} * @example * isSaving({ wp }) * // returns true or false * */ blockbite.getEditorType = () => { if (window.location.href.includes('post.php')) { return 'edit-post'; } else if (window.location.href.includes('site-editor.php')) { return 'edit-site'; } else { return undefined; } }; blockbite.getEditorMode = () => { return select('core/edit-post').getEditorMode(); }; /* * This function is used to fetch the template data * @param {String} * @param {String} * @returns {Object} * @example * fetchTemplate('1', 'wp_template') * // returns { id: 1, wp_id: 1, type: 'wp_template', title: { rendered: 'Template Title' } } * */ const fetchTemplate = async (stringId: string, template: string) => { let prefix = null; if (template === 'wp_template_part') { prefix = 'template-parts'; } else if (template === 'wp_template') { prefix = 'templates'; } const fetchResult = await apiFetch({ path: `/wp/v2/${prefix}/${stringId}`, }); return fetchResult; }; /* * This function is used to get the current post data * @param {Object} * @returns {Object} * @example * getTemplateData({ wp }) * // returns { id: 1, postType: 'post', templateType: 'Post Title' } * */ blockbite.getTemplateData = async (): Promise<{ id: string | number; postType: string; templateType: string; templateRef?: string | number; }> => { const editorTypeStr = blockbite.getEditorType(); if (editorTypeStr === 'edit-post') { return { id: select('core/editor').getCurrentPostId(), postType: select('core/editor').getCurrentPostType(), templateType: select('core/editor').getEditedPostAttribute('title'), }; } else if (editorTypeStr === 'edit-site') { const templateId = select('core/edit-site').getEditedPostId(); const templateType = select('core/edit-site').getEditedPostType(); return fetchTemplate(templateId, templateType).then( (data: { id: any; wp_id: any; type: any; title: { rendered: any } }) => { return { id: data.wp_id, postType: data.type, templateType: data.title.rendered, templateRef: data.id, }; } ); } }; blockbite.getDeviceType = () => { const { __experimentalGetPreviewDeviceType } = select('core/edit-post'); let deviceType = 'all'; if (__experimentalGetPreviewDeviceType) { deviceType = __experimentalGetPreviewDeviceType(); } if (deviceType === 'Mobile') { return 'xs'; } else if (deviceType === 'Tablet') { return 'md'; } else if (deviceType === 'Desktop') { return 'all'; } }; const getThemeColors = () => { const settings = select('core/block-editor').getSettings(); const themeColors = settings?.colors; const tokenName = 'b_color-'; let mappedColors = [] as DesignTokenProp[]; if (themeColors !== undefined) { mappedColors = themeColors.map((color: any, index: number) => { return { token: tokenName + index, value: color.color, label: color.name, name: color.name, } as DesignTokenProp; }); } return mappedColors; }; const getThemeFonts = () => { const settings = select('core/block-editor').getSettings() as any; const themeFontFamilies = settings?.__experimentalFeatures?.typography?.fontFamilies?.custom; let mappedFonts = [] as DesignTokenProp[]; if (themeFontFamilies !== undefined) { const tokenName = 'b_font-'; mappedFonts = themeFontFamilies.map((font: any, index: number) => { return { token: tokenName + index, value: font.name, label: font.name, name: font.name, } as DesignTokenProp; }); } return mappedFonts; }; // Helper function to map theme font sizes to design tokens const mapThemeFontSizes = ( themeFontSizes: any[], tokenPrefix: string ): DesignTokenProp[] => { return themeFontSizes.map((size, index) => ({ token: `${tokenPrefix}${index}`, value: size.size, name: size.name, })); }; // Helper function to apply global style overrides for headings const applyGlobalStyleOverrides = (elements: any, tokenPrefix: string) => { const headingLevels = ['h6', 'h5', 'h4', 'h3', 'h2', 'h1']; let newIndex = 0; let mappedFontSizes = [] as DesignTokenProp[]; headingLevels.forEach((heading) => { const fontSize = elements?.[heading]?.typography?.fontSize; // ignore default css variables if (fontSize && !fontSize.includes('var:preset|font-size')) { mappedFontSizes.push({ token: `${tokenPrefix}${newIndex}`, value: fontSize, name: heading, }); newIndex++; } }); return mappedFontSizes; }; // Main function to get the theme font sizes and apply global overrides const getThemeFontSizes = (globalStyles: any) => { const settings = select('core/block-editor').getSettings() as any; const tokenPrefix = 'b_fontsize-'; const themeFontSizes = settings?.fontSizes || []; // Step 1: Map theme font sizes let mappedFontSizes = mapThemeFontSizes(themeFontSizes, tokenPrefix); // Step 2: Apply global styles overrides, if they exist if (globalStyles?.styles?.elements) { mappedFontSizes = applyGlobalStyleOverrides( globalStyles.styles.elements, tokenPrefix ); } return mappedFontSizes; }; const getHeadings = () => { const settings = select('core/block-editor').getSettings() as any; const headings = settings?.__experimentalFeatures?.typography?.headings; return headings || []; }; blockbite.getNativeTheme = (globalStyles: any) => { const theme = { colors: [...getThemeColors()], fonts: [...getThemeFonts()], fontSizes: [...getThemeFontSizes(globalStyles)], headings: [...getHeadings()], }; return theme; }; /** * Update any block attributes by client id * @param clientId * @param newAttributes */ blockbite.updateBlockAttributes = (clientId: string, newAttributes: any) => { safeWpData() .dispatch('core/block-editor') .updateBlockAttributes(clientId, newAttributes); }; blockbite.getParentBlock = () => { const { clientId } = select('core/block-editor').getSelectedBlock(); const parents = wp.data.select('core/block-editor').getBlockParents(clientId); if (parents.length) { const parent = parents.pop(); return select('core/block-editor').getBlock(parent); } else { return null; } };