diff --git a/mu-plugins/blocks/ratings-bars/index.php b/mu-plugins/blocks/ratings-bars/index.php new file mode 100644 index 00000000..e9329933 --- /dev/null +++ b/mu-plugins/blocks/ratings-bars/index.php @@ -0,0 +1,20 @@ +context['postId']; +if ( ! $current_post_id ) { + return; +} + +/** + * Get the ratings data via filter, so that individual sites can provide + * this regardless of rating data format. + * + * @param array $data { + * Array of ratings data. + * + * The return value should use the following format. + * + * @type int $ratingsCount The total of ratings, must match sum of all + * values in ratings. + * @type int[] $ratings Rating count. The array must have 5 items, ex: + * [1 => count of 1-star, …, 5 => count of 5-star]. + * @type int $rating The average rating on a scale of 0 - 100. + * @type string $supportUrl URL to support forum. + * } + * @param int $current_post_id The ID of the current post. + */ +$data = apply_filters( 'wporg_ratings_data', array(), $current_post_id ); + +$defaults = array( + 'ratingsCount' => 0, + 'ratings' => [], + 'supportUrl' => '', +); + +$data = wp_parse_args( $data, $defaults ); + +if ( empty( $data['ratings'] ) || empty( $data['ratingsCount'] ) ) { + return; +} + +?> + diff --git a/mu-plugins/blocks/ratings-bars/src/block.json b/mu-plugins/blocks/ratings-bars/src/block.json new file mode 100644 index 00000000..a5ea5393 --- /dev/null +++ b/mu-plugins/blocks/ratings-bars/src/block.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 2, + "name": "wporg/ratings-bars", + "version": "0.1.0", + "title": "Ratings (bars)", + "category": "design", + "icon": "", + "description": "The breakdown of ratings displayed as bars for each rating value.", + "textdomain": "wporg", + "supports": { + "html": false + }, + "usesContext": [ "postId" ], + "editorScript": "file:./index.js", + "style": "file:./style-index.css", + "render": "file:../render.php" +} diff --git a/mu-plugins/blocks/ratings-bars/src/index.js b/mu-plugins/blocks/ratings-bars/src/index.js new file mode 100644 index 00000000..4f621505 --- /dev/null +++ b/mu-plugins/blocks/ratings-bars/src/index.js @@ -0,0 +1,25 @@ +/** + * WordPress dependencies + */ +import { registerBlockType } from '@wordpress/blocks'; +import ServerSideRender from '@wordpress/server-side-render'; +import { useBlockProps } from '@wordpress/block-editor'; + +/** + * Internal dependencies + */ +import metadata from './block.json'; +import './style.scss'; + +function Edit( { attributes, name } ) { + return ( +
+ +
+ ); +} + +registerBlockType( metadata.name, { + edit: Edit, + save: () => null, +} ); diff --git a/mu-plugins/blocks/ratings-bars/src/style.scss b/mu-plugins/blocks/ratings-bars/src/style.scss new file mode 100644 index 00000000..d066b8eb --- /dev/null +++ b/mu-plugins/blocks/ratings-bars/src/style.scss @@ -0,0 +1,65 @@ +.wp-block-wporg-ratings-bars { + list-style: none; + padding-inline-start: unset; +} + +.wporg-ratings-bars__bar { + a { + margin-bottom: 4px; + display: flex; + align-items: center; + gap: var(--wp--preset--spacing--10); + text-decoration: none; + + &:hover { + text-decoration: underline; + } + } + + &:last-child a { + margin-bottom: 0; + } +} + +.wporg-ratings-bars__bar-label { + flex-basis: 4em; + flex-shrink: 0; +} + +.wporg-ratings-bars__bar-count { + flex-basis: 2em; + flex-shrink: 0; + text-align: right; +} + +.wporg-ratings-bars__bar-background { + display: inline-block; + background-color: var(--wp--preset--color--light-grey-2); + position: relative; + width: 100%; + height: var(--wp--preset--spacing--20); +} + +.wporg-ratings-bars__bar-foreground { + position: absolute; + inset: 0; + right: auto; + background-color: var(--wp--custom--wporg-ratings-stars--color--fill, #e26f56); +} + +@supports (grid-template-columns: subgrid) { + .wp-block-wporg-ratings-bars { + display: grid; + gap: 4px var(--wp--preset--spacing--10); + grid-template-columns: auto 1fr auto; + + .wporg-ratings-bars__bar, + .wporg-ratings-bars__bar a { + display: grid; + grid-column: span 3; + grid-template-columns: subgrid; + margin-bottom: unset; + gap: unset; + } + } +} diff --git a/mu-plugins/blocks/ratings-stars/index.php b/mu-plugins/blocks/ratings-stars/index.php new file mode 100644 index 00000000..0a2be3f1 --- /dev/null +++ b/mu-plugins/blocks/ratings-stars/index.php @@ -0,0 +1,20 @@ +context['postId']; +if ( ! $current_post_id ) { + return; +} + +/** This filter is documented in mu-plugins/blocks/ratings-bars/render.php */ +$data = apply_filters( 'wporg_ratings_data', array(), $current_post_id ); + +$defaults = array( + 'rating' => 0, +); + +$data = wp_parse_args( $data, $defaults ); + +if ( empty( $data['rating'] ) ) { + return; +} + +?> +
> + + + +
+ +
+ +
+ '; + } else if ( $i + 0.5 === $display_rating ) { + echo ''; + } else { + echo ''; + } + } + ?> +
+ +
+ ' . $display_rating . '' // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + ); + ?> +
+ +
diff --git a/mu-plugins/blocks/ratings-stars/src/block.json b/mu-plugins/blocks/ratings-stars/src/block.json new file mode 100644 index 00000000..7b991bca --- /dev/null +++ b/mu-plugins/blocks/ratings-stars/src/block.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 2, + "name": "wporg/ratings-stars", + "version": "0.1.0", + "title": "Ratings (stars)", + "category": "design", + "icon": "", + "description": "The average rating displayed as stars.", + "textdomain": "wporg", + "supports": { + "html": false + }, + "usesContext": [ "postId" ], + "editorScript": "file:./index.js", + "style": "file:./style-index.css", + "render": "file:../render.php" +} diff --git a/mu-plugins/blocks/ratings-stars/src/index.js b/mu-plugins/blocks/ratings-stars/src/index.js new file mode 100644 index 00000000..4f621505 --- /dev/null +++ b/mu-plugins/blocks/ratings-stars/src/index.js @@ -0,0 +1,25 @@ +/** + * WordPress dependencies + */ +import { registerBlockType } from '@wordpress/blocks'; +import ServerSideRender from '@wordpress/server-side-render'; +import { useBlockProps } from '@wordpress/block-editor'; + +/** + * Internal dependencies + */ +import metadata from './block.json'; +import './style.scss'; + +function Edit( { attributes, name } ) { + return ( +
+ +
+ ); +} + +registerBlockType( metadata.name, { + edit: Edit, + save: () => null, +} ); diff --git a/mu-plugins/blocks/ratings-stars/src/style.scss b/mu-plugins/blocks/ratings-stars/src/style.scss new file mode 100644 index 00000000..6e4e7bc8 --- /dev/null +++ b/mu-plugins/blocks/ratings-stars/src/style.scss @@ -0,0 +1,29 @@ +.wp-block-wporg-ratings-stars { + display: flex; + align-items: center; +} + +.wporg-ratings-stars__icons { + display: inline-flex; + + svg { + height: 32px; + width: 32px; + margin-inline-start: -6px; + fill: var(--wp--custom--wporg-ratings-stars--color--fill, #e26f56); + } + + // Flip the half-star for RTL views. + .rtl & .is-star-half { + transform: rotateY(-180deg); + } +} + +.wporg-ratings-stars__label { + font-size: var(--wp--preset--font-size--small); + color: var(--wp--preset--color--charcoal-4); + + .wporg-ratings-stars__icons + & { + margin-inline-start: 0.5em; + } +} diff --git a/mu-plugins/loader.php b/mu-plugins/loader.php index 486a31bc..b628c3c1 100644 --- a/mu-plugins/loader.php +++ b/mu-plugins/loader.php @@ -40,6 +40,8 @@ require_once __DIR__ . '/blocks/query-filter/index.php'; require_once __DIR__ . '/blocks/query-has-results/index.php'; require_once __DIR__ . '/blocks/query-total/index.php'; +require_once __DIR__ . '/blocks/ratings-bars/index.php'; +require_once __DIR__ . '/blocks/ratings-stars/index.php'; require_once __DIR__ . '/blocks/sidebar-container/index.php'; require_once __DIR__ . '/blocks/screenshot-preview/block.php'; require_once __DIR__ . '/blocks/screenshot-preview-block/block.php';