PluginProbe
Extendify / 3.2.1
Extendify v3.2.1
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
extendify / src / Agent / abilities / theme-settings.js

theme-settings.js in Extendify 3.2.1, at src/Agent/abilities/theme-settings.js

113 lines 3.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import apiFetch from '@wordpress/api-fetch';
2 import { __ } from '@wordpress/i18n';
3
4 const reads = ['colors', 'fonts', 'variations'];
5
6 const activeStylesheet = async () => {
7 const themes = await apiFetch({ path: '/wp/v2/themes?status=active' });
8 return themes[0]?.stylesheet;
9 };
10
11 const preset = (value) =>
12 Array.isArray(value)
13 ? value
14 : (value?.custom ?? value?.theme ?? value?.default);
15
16 const currentDesign = async (stylesheet) => {
17 const { globalStylesPostID } = window.extSharedData;
18 const [theme, user] = await Promise.all([
19 apiFetch({
20 path: `/wp/v2/global-styles/themes/${stylesheet}?context=edit`,
21 }),
22 globalStylesPostID
23 ? apiFetch({
24 path: `/wp/v2/global-styles/${globalStylesPostID}?context=edit`,
25 })
26 : null,
27 ]);
28 return { theme, user };
29 };
30
31 const colors = ({ theme, user }) =>
32 (
33 preset(user?.settings?.color?.palette) ??
34 preset(theme?.settings?.color?.palette) ??
35 []
36 ).map(({ name, slug, color }) => ({ name, slug, color }));
37
38 const named = (value, families) => {
39 const slug = value?.match(/font-family--([\w-]+)/)?.[1] ?? value;
40 return families.find((family) => family.slug === slug)?.name ?? slug;
41 };
42
43 const fonts = ({ theme, user }) => {
44 const families = [
45 ...(preset(user?.settings?.typography?.fontFamilies) ?? []),
46 ...(preset(theme?.settings?.typography?.fontFamilies) ?? []),
47 ];
48
49 return {
50 body: named(
51 user?.styles?.typography?.fontFamily ??
52 theme?.styles?.typography?.fontFamily,
53 families,
54 ),
55 heading: named(
56 user?.styles?.elements?.heading?.typography?.fontFamily ??
57 theme?.styles?.elements?.heading?.typography?.fontFamily,
58 families,
59 ),
60 };
61 };
62
63 const styleVariations = async (stylesheet) => {
64 const offered = await apiFetch({
65 path: `/wp/v2/global-styles/themes/${stylesheet}/variations`,
66 });
67
68 return offered
69 .filter(({ title }) => title)
70 .map(({ title, slug }) => ({
71 title,
72 slug: slug ?? title.toLowerCase().trim().replace(/\s+/g, '-'),
73 }));
74 };
75
76 export const themeSettings = {
77 name: 'extendify/theme-settings',
78 label: __('Design settings', 'extendify-local'),
79 description:
80 'The design this site is set to: the colours in its palette, the fonts its text is set in, and the style variations its theme offers to switch between.',
81 inputSchema: {
82 type: 'object',
83 properties: {
84 include: {
85 type: 'array',
86 items: { type: 'string', enum: reads },
87 description: 'Which of these to return. Omit it for all of them.',
88 },
89 },
90 },
91 annotations: { readonly: true },
92 execute: async ({ include } = {}) => {
93 const wanted = include?.length
94 ? include.filter((key) => reads.includes(key))
95 : reads;
96 const stylesheet = await activeStylesheet();
97 if (!stylesheet) return { error: 'The active theme could not be read.' };
98
99 const design =
100 wanted.includes('colors') || wanted.includes('fonts')
101 ? await currentDesign(stylesheet)
102 : null;
103
104 return {
105 ...(wanted.includes('colors') && { colors: colors(design) }),
106 ...(wanted.includes('fonts') && { fonts: fonts(design) }),
107 ...(wanted.includes('variations') && {
108 variations: await styleVariations(stylesheet),
109 }),
110 };
111 },
112 };
113