diff --git a/bin/api-docs/gen-theme-reference.js b/bin/api-docs/gen-theme-reference.js
index f638bb708890a..0ea9e282e5463 100644
--- a/bin/api-docs/gen-theme-reference.js
+++ b/bin/api-docs/gen-theme-reference.js
@@ -74,6 +74,42 @@ const keys = ( maybeObject ) => {
return Object.keys( maybeObject );
};
+/**
+ * Get definition from ref.
+ *
+ * @param {string} ref
+ * @return {Object} definition
+ * @throws {Error} If the referenced definition is not found in 'themejson.definitions'.
+ *
+ * @example
+ * getDefinition( '#/definitions/typographyProperties/properties/fontFamily' )
+ * // returns themejson.definitions.typographyProperties.properties.fontFamily
+ */
+const resolveDefinitionRef = ( ref ) => {
+ const refParts = ref.split( '/' );
+ const definition = refParts[ refParts.length - 1 ];
+ if ( ! themejson.definitions[ definition ] ) {
+ throw new Error( `Can't resolve '${ ref }'. Definition not found` );
+ }
+ return themejson.definitions[ definition ];
+};
+
+/**
+ * Get properties from an array.
+ *
+ * @param {Object} items
+ * @return {Object} properties
+ */
+const getPropertiesFromArray = ( items ) => {
+ // if its a $ref resolve it
+ if ( items.$ref ) {
+ return resolveDefinitionRef( items.$ref ).properties;
+ }
+
+ // otherwise just return the properties
+ return items.properties;
+};
+
/**
* Convert settings properties to markup.
*
@@ -96,7 +132,9 @@ const getSettingsPropertiesMarkup = ( struct ) => {
const def = 'default' in props[ key ] ? props[ key ].default : '';
const ps =
props[ key ].type === 'array'
- ? keys( props[ key ].items.properties ).sort().join( ', ' )
+ ? keys( getPropertiesFromArray( props[ key ].items ) )
+ .sort()
+ .join( ', ' )
: '';
markup += `| ${ key } | ${ props[ key ].type } | ${ def } | ${ ps } |\n`;
} );
diff --git a/schemas/README.md b/schemas/README.md
index 1b2d8992cccb9..fa695115f33ab 100644
--- a/schemas/README.md
+++ b/schemas/README.md
@@ -1,6 +1,6 @@
# Schemas
-The collection of schemas used in WordPress, including the `theme.json` and `block.json` schemas.
+The collection of schemas used in WordPress, including the `theme.json`, `block.json` and `font-collection.json` schemas.
JSON schemas are used by code editors to offer tooltips, autocomplete, and validation.
@@ -24,6 +24,14 @@ Or in your `theme.json`:
}
```
+Or in your `font-collection.json`:
+
+```json
+{
+ "$schema": "https://schemas.wp.org/trunk/font-collection.json"
+}
+```
+
For a specific version of the schema, replace `trunk` with `wp/X.X`:
```json
@@ -56,8 +64,16 @@ To allow this you will need to:
}
```
+- update your font collections's `font-collection.json` to include:
+
+```json
+{
+ "$schema": "file://{{FULL_FILE_PATH}}/schemas/json/font-collection.json"
+}
+```
+
Be sure to replace `{{FULL_FILE_PATH}}` with the full local path to your Gutenberg repo.
-With this in place you should now be able to edit either `schemas/json/theme .json` or `schemas/json/block.json` in order to see changes reflected in `theme.json` or `block.json` in your IDE.
+With this in place you should now be able to edit either `schemas/json/theme .json`, `schemas/json/block.json` or `schemas/json/font-collection.json` in order to see changes reflected in `theme.json`, `block.json` or `font-collection.json` in your IDE.
diff --git a/schemas/json/font-collection.json b/schemas/json/font-collection.json
new file mode 100644
index 0000000000000..a6ca2b1412e6d
--- /dev/null
+++ b/schemas/json/font-collection.json
@@ -0,0 +1,59 @@
+{
+ "title": "JSON schema for WordPress Font Collections",
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "type": "object",
+ "properties": {
+ "$schema": {
+ "description": "JSON schema URI for font-collection.json.",
+ "type": "string"
+ },
+ "version": {
+ "description": "Version of font-collection.json schema to use.",
+ "type": "integer",
+ "enum": [ 1 ]
+ },
+ "font_families": {
+ "type": "array",
+ "description": "Array of font families ready to be installed",
+ "items": {
+ "type": "object",
+ "properties": {
+ "font_family_settings": {
+ "description": "Font family settings as in theme.json",
+ "allOf": [
+ { "$ref": "./theme.json#/definitions/fontFamily" }
+ ]
+ },
+ "categories": {
+ "type": "array",
+ "description": "Array of category slugs",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "required": [ "font_family_settings" ],
+ "additionalProperties": false
+ }
+ },
+ "categories": {
+ "type": "array",
+ "description": "Array of category objects",
+ "items": {
+ "type": "object",
+ "properties": {
+ "slug": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ }
+ },
+ "required": [ "slug", "name" ],
+ "additionalProperties": false
+ }
+ }
+ },
+ "additionalProperties": false,
+ "required": [ "$schema", "version", "font_families" ]
+}
diff --git a/schemas/json/theme.json b/schemas/json/theme.json
index 9f633fc77ec75..6ae8d15df63d2 100644
--- a/schemas/json/theme.json
+++ b/schemas/json/theme.json
@@ -614,132 +614,136 @@
"description": "Font family presets for the font family selector.\nGenerates a single custom property (`--wp--preset--font-family--{slug}`) per preset value.",
"type": "array",
"items": {
- "type": "object",
- "properties": {
- "name": {
- "description": "Name of the font family preset, translatable.",
- "type": "string"
- },
- "slug": {
- "description": "Kebab-case unique identifier for the font family preset.",
- "type": "string"
- },
- "fontFamily": {
- "description": "CSS font-family value.",
+ "$ref": "#/definitions/fontFamily"
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ },
+ "fontFamily": {
+ "type": "object",
+ "description": "Font family preset",
+ "properties": {
+ "name": {
+ "description": "Name of the font family preset, translatable.",
+ "type": "string"
+ },
+ "slug": {
+ "description": "Kebab-case unique identifier for the font family preset.",
+ "type": "string"
+ },
+ "fontFamily": {
+ "description": "CSS font-family value.",
+ "type": "string"
+ },
+ "preview": {
+ "description": "URL to a preview image of the font family.",
+ "type": "string"
+ },
+ "fontFace": {
+ "description": "Array of font-face declarations.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "fontFamily": {
+ "description": "CSS font-family value.",
+ "type": "string",
+ "default": ""
+ },
+ "fontStyle": {
+ "description": "CSS font-style value.",
+ "type": "string",
+ "default": "normal"
+ },
+ "fontWeight": {
+ "description": "List of available font weights, separated by a space.",
+ "default": "400",
+ "oneOf": [
+ {
"type": "string"
},
- "preview": {
- "description": "URL to a preview image of the font family.",
+ {
+ "type": "integer"
+ }
+ ]
+ },
+ "fontDisplay": {
+ "description": "CSS font-display value.",
+ "type": "string",
+ "default": "fallback",
+ "enum": [
+ "auto",
+ "block",
+ "fallback",
+ "swap",
+ "optional"
+ ]
+ },
+ "src": {
+ "description": "Paths or URLs to the font files.",
+ "oneOf": [
+ {
"type": "string"
},
- "fontFace": {
- "description": "Array of font-face declarations.",
+ {
"type": "array",
"items": {
- "type": "object",
- "properties": {
- "fontFamily": {
- "description": "CSS font-family value.",
- "type": "string",
- "default": ""
- },
- "fontStyle": {
- "description": "CSS font-style value.",
- "type": "string",
- "default": "normal"
- },
- "fontWeight": {
- "description": "List of available font weights, separated by a space.",
- "default": "400",
- "oneOf": [
- {
- "type": "string"
- },
- {
- "type": "integer"
- }
- ]
- },
- "fontDisplay": {
- "description": "CSS font-display value.",
- "type": "string",
- "default": "fallback",
- "enum": [
- "auto",
- "block",
- "fallback",
- "swap",
- "optional"
- ]
- },
- "src": {
- "description": "Paths or URLs to the font files.",
- "oneOf": [
- {
- "type": "string"
- },
- {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- ],
- "default": []
- },
- "fontStretch": {
- "description": "CSS font-stretch value.",
- "type": "string"
- },
- "ascentOverride": {
- "description": "CSS ascent-override value.",
- "type": "string"
- },
- "descentOverride": {
- "description": "CSS descent-override value.",
- "type": "string"
- },
- "fontVariant": {
- "description": "CSS font-variant value.",
- "type": "string"
- },
- "fontFeatureSettings": {
- "description": "CSS font-feature-settings value.",
- "type": "string"
- },
- "fontVariationSettings": {
- "description": "CSS font-variation-settings value.",
- "type": "string"
- },
- "lineGapOverride": {
- "description": "CSS line-gap-override value.",
- "type": "string"
- },
- "sizeAdjust": {
- "description": "CSS size-adjust value.",
- "type": "string"
- },
- "unicodeRange": {
- "description": "CSS unicode-range value.",
- "type": "string"
- },
- "preview": {
- "description": "URL to a preview image of the font face.",
- "type": "string"
- }
- },
- "required": [ "fontFamily", "src" ],
- "additionalProperties": false
+ "type": "string"
}
}
- },
- "additionalProperties": false
+ ],
+ "default": []
+ },
+ "fontStretch": {
+ "description": "CSS font-stretch value.",
+ "type": "string"
+ },
+ "ascentOverride": {
+ "description": "CSS ascent-override value.",
+ "type": "string"
+ },
+ "descentOverride": {
+ "description": "CSS descent-override value.",
+ "type": "string"
+ },
+ "fontVariant": {
+ "description": "CSS font-variant value.",
+ "type": "string"
+ },
+ "fontFeatureSettings": {
+ "description": "CSS font-feature-settings value.",
+ "type": "string"
+ },
+ "fontVariationSettings": {
+ "description": "CSS font-variation-settings value.",
+ "type": "string"
+ },
+ "lineGapOverride": {
+ "description": "CSS line-gap-override value.",
+ "type": "string"
+ },
+ "sizeAdjust": {
+ "description": "CSS size-adjust value.",
+ "type": "string"
+ },
+ "unicodeRange": {
+ "description": "CSS unicode-range value.",
+ "type": "string"
+ },
+ "preview": {
+ "description": "URL to a preview image of the font face.",
+ "type": "string"
}
- }
- },
- "additionalProperties": false
+ },
+ "required": [ "fontFamily", "src" ],
+ "additionalProperties": false
+ }
}
- }
+ },
+ "additionalProperties": false
},
"settingsPropertiesCustom": {
"type": "object",