Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dashicons: Implement with Interactivity API #531

Open
wants to merge 28 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
0f5564f
Add experimental-modules build flag
sirreal Jul 22, 2024
b7b195b
Try making a block
sirreal Jul 23, 2024
7092fe9
PICKME: Upgrade @wordpress/scripts
sirreal Jul 23, 2024
f6120b8
Not rendering a post now
sirreal Jul 23, 2024
1119a71
starting to work properly
sirreal Jul 23, 2024
5eb1e73
Close to working
sirreal Jul 23, 2024
dad1fea
Remove redundant property
sirreal Jul 23, 2024
4c5280a
Copy buttons working
sirreal Jul 24, 2024
fc1efc6
Remove unused context
sirreal Jul 24, 2024
b1bfd0e
Localize copy texts
sirreal Jul 24, 2024
a04fd43
Add icon to url query param when selecting
sirreal Jul 24, 2024
a5a30dd
Revert "Add icon to url query param when selecting"
sirreal Jul 24, 2024
48891b1
Filter icons
sirreal Jul 24, 2024
4f3195c
Handle updating URL for selected icon and moving to page top
sirreal Jul 24, 2024
b33aa49
Handle icon query param to select icon
sirreal Jul 24, 2024
4ee4665
Upgrade fragment-style links to query param
sirreal Jul 24, 2024
db61bb5
Disable server-side intermediate derived state
sirreal Jul 24, 2024
0f8fbcc
Remove unused block properties
sirreal Jul 24, 2024
9fdbe14
Remove console.log
sirreal Jul 24, 2024
fe83c78
Fix incorrect asset version argument, use filemtime
sirreal Jul 26, 2024
d811054
Fix dirname levels lint
sirreal Jul 26, 2024
51a382c
Fix translation function __ and textdomain wporg
sirreal Jul 26, 2024
1023929
Update store namespace to wporg/developer/dashicons-page
sirreal Jul 26, 2024
5734a4f
Fix =,=> alignment lints
sirreal Jul 26, 2024
dab9a18
Fix whitespace lints
sirreal Jul 26, 2024
44d4287
Move dashicons page css into block viewStyle
sirreal Jul 26, 2024
579eeea
Fix replace regex to run global and allow -
sirreal Jul 26, 2024
e24e9c1
Add ignore comment on valid user input usage
sirreal Jul 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"license": "GPL-2.0-or-later",
"private": true,
"dependencies": {
"@wordpress/scripts": "27.1.0"
"@wordpress/scripts": "28.3.0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume that the code is going to work with WordPress 6.7 because otherwise, it would fail with the missing JSX runtime script dependency.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good callout!

The v28 changelog reads:

Breaking Changes
Note If you're using @wordpress/scripts for building JS scripts to target WordPress 6.5 or earlier, you should not upgrade to this version and continue using @wordpress/scripts@27.

I think the site uses latest WordPress, so if it's on WP 6.6, it should work if that comment is accurate. Do you know if it's WordPress 6.6 or 6.7 that will use the new JSX runtime?

@ryelle can you confirm the site runs on latest WordPress release (6.6.x at this time)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, 6.6 is fine, too. I assume that it's sartisfied here. However, I wanted to ensure we don't see any surprises when deploying.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WordPress.org runs trunk & (usually) the latest Gutenberg version (the exception is the Support Forums due to conflicts with blocks-everywhere, so we used a pinned version there). So we should be set with this version change. It also worked fine on my sandbox, which matches production versions.

},
"devDependencies": {
"@wordpress/env": "9.2.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@
require_once __DIR__ . '/src/search-filters/index.php';
require_once __DIR__ . '/src/search-post/index.php';
require_once __DIR__ . '/src/search-results-context/index.php';
require_once __DIR__ . '/src/dashicons-page/index.php';

add_action( 'init', __NAMESPACE__ . '\\init' );
add_filter( 'wporg_block_site_breadcrumbs', __NAMESPACE__ . '\set_site_breadcrumbs' );
Expand Down
12 changes: 6 additions & 6 deletions source/wp-content/themes/wporg-developer-2023/package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "wporg-developer-2023",
"version": "1.0.0",
"description": "Theme for WordPress Developer Resources",
"name": "wporg-developer-2023",
"version": "1.0.0",
"description": "Theme for WordPress Developer Resources",
"author": "WordPress.org",
"license": "GPL-2.0-or-later",
"private": true,
"devDependencies": {
"@wordpress/eslint-plugin": "^17.7.0",
"@wordpress/scripts": "27.1.0"
"@wordpress/scripts": "28.3.0"
},
"eslintConfig": {
"extends": "../../../../.eslintrc.js"
Expand All @@ -16,8 +16,8 @@
"extends": "../../../../.stylelintrc"
},
"scripts": {
"build": "wp-scripts build",
"start": "wp-scripts start",
"build": "wp-scripts build --experimental-modules",
"start": "wp-scripts start --experimental-modules",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could pull this out to its own PR to upgrade the package and add this flag. I don't think it should affect anything else.

"lint:js": "wp-scripts lint-js src",
"lint:css": "wp-scripts lint-style *.css src/**/*.scss",
"format": "wp-scripts format src"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "wporg/dashicons-page",
"title": "Dashicons page",
"category": "widgets",
"description": "Dashicons page block",
"keywords": [],
"textdomain": "wporg",
"attributes": {},
"supports": {
"inserter": false,
"interactivity": true
},
"render": "file:./render.php",
"viewScriptModule": "file:./view.js"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
/**
* Block Name: Dashicons Page
* Description: Dashicons page block.
*
* @package wporg
*/

namespace WordPressdotorg\Theme\Developer_2023\Dashicons_Page;

add_action( 'init', __NAMESPACE__ . '\init' );

/**
* Registers the block using the metadata loaded from the `block.json` file.
* Behind the scenes, it registers also all assets so they can be enqueued
* through the block editor in the corresponding context.
*
* @see https://developer.wordpress.org/reference/functions/register_block_type/
*/
function init() {
register_block_type(
dirname( dirname( __DIR__ ) ) . '/build/dashicons-page/block.json'
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
<?php

namespace WordPressdotorg\Theme\Developer_2023\Block_Dashicons_Page;

require_once dirname( dirname( __DIR__ ) ) . '/inc/dashicons.php';

wp_enqueue_style(
'dashicons-page',
get_stylesheet_directory_uri() . '/stylesheets/page-dashicons.css',
array(),
get_stylesheet_directory() . '/stylesheets/page-dashicons.css'
sirreal marked this conversation as resolved.
Show resolved Hide resolved
);
sirreal marked this conversation as resolved.
Show resolved Hide resolved

$icons = array();
$icons_sections = array();

foreach ( \DevHub_Dashicons::get_dashicons() as $section_group => $section ) {
$icon_section = array(
'label' => $section['label'],
'slug' => sanitize_title( $section_group ),
'icons' => array(),
);
foreach ( $section['icons'] as $k => $v ) {
$icons[$k] = $v;
$icons[$k]['sectionLabel'] = $section['label'];
$icon_section['icons'][] = $k;
}
$icons_sections[] = $icon_section;
}

$selected_icon = $_GET['icon'] ?? '';
sirreal marked this conversation as resolved.
Show resolved Hide resolved
if ( ! array_key_exists( $selected_icon, $icons ) ) {
$selected_icon = array_rand( $icons );
}

wp_interactivity_config(
'wporg/dashicons-page',
sirreal marked this conversation as resolved.
Show resolved Hide resolved
array(
'texts' => array(
'copyCss' => _( 'Copy this, then paste in your CSS :before selector.' ),
'copyHtml' => _( 'Copy this, then paste in your HTML.' ),
'copyGlyph' => _( 'Copy this, then paste in your Photoshop textfield.' ),
),
sirreal marked this conversation as resolved.
Show resolved Hide resolved
'icons' => $icons,
)
);

wp_interactivity_state(
'wporg/dashicons-page',
array(
/*
* START: Derived state.
*
* All these "derived state" getters must be defined in view.js as well
*/
'iconClass' => function() {
return 'dashicons ' . wp_interactivity_get_context()['icon'];
},
'sectionAnchorTarget' => function() {
return 'icons-' . wp_interactivity_get_context()['section']['slug'];
},
'sectionAnchorHref' => function () {
return '#icons-' . wp_interactivity_get_context()['section']['slug'];
},
'iconSectionLabel' => function() {
return wp_interactivity_get_context()['section']['label'];
},

/*
* @todo Restore this when Core supports server-side derived state in non-final position.
* @see https://github.com/WordPress/wordpress-develop/pull/7075
* Expected in WordPress 6.6.2
*/
// 'eachIcon' => function() use ( $icons ) {
// return $icons[ wp_interactivity_get_context()['icon'] ];
// },

/*
* END: Derived state
*/

'iconsSections' => $icons_sections,
'selectedIcon' => array( $selected_icon ),
'filter' => '',
'style' => '',
)
);

$deprecation_notice = sprintf(
'<!-- wp:wporg/notice {"type":"alert"} -->
<div class="wp-block-wporg-notice is-alert-notice">
<div class="wp-block-wporg-notice__icon"></div>
<div class="wp-block-wporg-notice__content"><p>%s</p></div>
</div>
<!-- /wp:wporg/notice -->',
__( 'The Dashicons project is no longer accepting icon requests. Here’s why:&nbsp;<a href="https://make.wordpress.org/design/2020/04/20/next-steps-for-dashicons/">Next steps for Dashicons</a>.', 'wporg' )
);

?>
<div id="content-area" <?php body_class( 'dashicons-page' ); ?> data-wp-interactive="wporg/dashicons-page" data-wp-init="init">
<style data-wp-text="state.style"></style>
<main id="main" <?php post_class( 'site-main' ); ?> role="main">

<?php echo do_blocks( wp_kses_post( $deprecation_notice ) ); ?>

<div class="details clear">
<div id="glyph">
<template data-wp-each--icon="state.selectedIcon">
<div data-wp-bind--class="state.iconClass"></div>
<div class="info">
<span><strong data-wp-text="state.eachIcon.sectionLabel"></strong></span>
<span class="name"><code data-wp-text="context.icon"></code></span>
<span class="charCode"><code data-wp-text="state.eachIcon.code"></code></span>
<span class="link"><button data-wp-on--click="copyClickHandlers.css" type="button"><?php _e( 'Copy CSS', 'wporg' ); ?></button></span>
<span class="link"><button data-wp-on--click="copyClickHandlers.html" type="button"><?php _e( 'Copy HTML', 'wporg' ); ?></button></span>
<span class="link"><button data-wp-on--click="copyClickHandlers.glyph" type="button"><?php _e( 'Copy Glyph', 'wporg' ); ?></button></span>
</div>
</template>
</div>
<div class="entry-content">
<?php the_content(); ?>
</div><!-- .entry-content -->
<div class="icon-filter">
<input data-wp-on--input="handleIconFilter" placeholder="<?php esc_attr_e( 'Filter&hellip;', 'wporg' ); ?>" name="search" id="search" type="text" value="" maxlength="150">
</div>
</div>
<div id="icons">
<div id="iconlist">
<template data-wp-each--section="state.iconsSections">
<h4 data-wp-bind--id="state.sectionAnchorTarget">
<span data-wp-text="context.section.label"></span>
<a data-wp-bind--href="state.sectionAnchorHref" class="anchor"><span aria-hidden="true">#</span><span class="screen-reader-text" data-wp-text="context.section.label"></span></a>
</h4>
<ul>
<template data-wp-each--icon="context.section.icons" >
<li data-wp-bind--data-keywords="state.eachIcon.keywords" data-wp-bind--class="state.iconClass" data-wp-on--click="handleIconClick">
<span data-wp-text="state.eachIcon.label"></span>
</li>
</template>
</ul>
</template>
</div>
</div>

<div id="instructions">
<h3><?php _e( 'WordPress Usage', 'wporg' ); ?></h3>
<p>
<?php printf(
__( 'Admin menu items can be added with <code><a href="%1$s">register_post_type()</a></code> and <code><a href="%2$s">add_menu_page()</a></code>, which both have an option to set an icon. To show the current icon, you should pass in %3$s.', 'wporg' ),
'https://developer.wordpress.org/reference/functions/register_post_type/',
'https://developer.wordpress.org/reference/functions/add_menu_page/',
'<code>\'dashicons-<span id="wp-class-example">{icon}</span>\'</code>'
); ?></p>

<h4><?php _e( 'Examples', 'wporg' ); ?></h4>
<p><?php printf(
__( 'In <code><a href="%s">register_post_type()</a></code>, set <code>menu_icon</code> in the arguments array.', 'wporg' ),
'https://developer.wordpress.org/reference/functions/register_post_type/'
); ?></p>

<pre>&lt;?php
/**
* Register the Product post type with a Dashicon.
*
* @see register_post_type()
*/
function wpdocs_create_post_type() {
register_post_type( 'acme_product',
array(
'labels' => array(
'name' => __( 'Products', 'textdomain' ),
'singular_name' => __( 'Product', 'textdomain' )
),
'public' => true,
'has_archive' => true,
'menu_icon' => 'dashicons-products',
)
);
}
add_action( 'init', 'wpdocs_create_post_type', 0 );
</pre>
<p>
<?php printf(
__( 'The function <code><a href="%s">add_menu_page()</a></code> accepts a parameter after the callback function for an icon URL, which can also accept a dashicons class.', 'wporg' ),
'https://developer.wordpress.org/reference/functions/add_menu_page/'
); ?></p>
<pre>&lt;?php
/**
* Register a menu page with a Dashicon.
*
* @see add_menu_page()
*/
function wpdocs_add_my_custom_menu() {
// Add an item to the menu.
add_menu_page(
__( 'My Page', 'textdomain' ),
__( 'My Title', 'textdomain' ),
'manage_options',
'my-page',
'my_admin_page_function',
'dashicons-admin-media'
);
}</pre>
<h3><?php _e( 'CSS/HTML Usage', 'wporg' ); ?></h3>
<p><?php _e( "If you want to use dashicons in the admin outside of the menu, there are two helper classes you can use. These are <code>dashicons-before</code> and <code>dashicons</code>, and they can be thought of as setting up dashicons (since you still need your icon's class, too).", 'wporg' ); ?></p>
<h4><?php _e( 'Examples', 'wporg' ); ?></h4>
<p><?php _e( 'Adding an icon to a header, with the <code>dashicons-before</code> class. This can be added right to the element with text.', 'wporg' ); ?></p>
<pre>
&lt;h2 class="dashicons-before dashicons-smiley"&gt;<?php _e( 'A Cheerful Headline', 'wporg' ); ?>&lt;/h2&gt;
</pre>
<p><?php _e( 'Adding an icon to a header, with the <code>dashicons</code> class. Note that here, you need extra markup specifically for the icon.', 'wporg' ); ?></p>
<pre>
&lt;h2&gt;&lt;span class="dashicons dashicons-smiley"&gt;&lt;/span&gt; <?php _e( 'A Cheerful Headline', 'wporg' ); ?>&lt;/h2&gt;
</pre>
<h3><?php _e( 'Block Usage', 'wporg' ); ?></h3>
<p><?php _e( 'The block editor supports use of dashicons as block icons and as its own component.', 'wporg' ); ?></p>
<h4><?php _e( 'Examples', 'wporg' ); ?></h4>
<p>
<?php printf(
/* translators: %s: URL to Block Editor Handbook for registering a block. */
__( 'Adding an icon to a block. The <code>registerBlockType</code> function accepts a parameter "icon" which accepts the name of a dashicon. The provided example is truncated. See the <a href="%s">full example</a> in the Block Editor Handbook.', 'wporg' ),
'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/writing-your-first-block-type/#registering-the-block'
); ?></p>
<pre>
registerBlockType( 'gutenberg-examples/example-01-basic-esnext', {
apiVersion: 2,
title: 'Example: Basic (esnext)',
icon: 'universal-access-alt',
category: 'design',
example: {},
edit() {},
save() {},
} );
</pre>
<p>
<?php printf(
/* translators: %s: URL to handbook page for Dashicon component. */
__( 'Using an icon as a component. A dedicated <code>Dashicon</code> component is available. See the <a href="%s">related documentation</a> in the Block Editor Handbook.', 'wporg' ),
'https://developer.wordpress.org/block-editor/reference-guides/components/dashicon/'
); ?></p>
<pre>
import { Dashicon } from '@wordpress/components';

const MyDashicon = () =&gt; (
&lt;div&gt;
&lt;Dashicon icon="admin-home" /&gt;
&lt;Dashicon icon="products" /&gt;
&lt;Dashicon icon="wordpress" /&gt;
&lt;/div&gt;
);
</pre>
<h3><?php _e( 'Photoshop Usage', 'wporg' ); ?></h3>
<p><?php _e( 'Use the .OTF version of the font for Photoshop mockups, the web-font versions won\'t work. For most accurate results, pick the "Sharp" font smoothing.', 'wporg' ); ?></p>
</div><!-- /#instructions -->
</main><!-- #main -->
<!-- Required for the Copy Glyph functionality -->
<div id="temp" style="display:none;"></div>
<!--
<script type="text/html" id="tmpl-glyphs">
</script>
-->
</div><!-- #primary -->
Loading
Loading