Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
1d2ef9a
add dashboard widget Suspense render demo
retrofox Apr 23, 2026
67b33ab
Add activity widget scaffolding
simison Apr 28, 2026
b9756d8
Refactor activity widget
simison Apr 28, 2026
fdf339b
Refactor activity widget simpler format
simison Apr 28, 2026
f851b3c
Scaffold quick draft
simison Apr 28, 2026
753a5a1
Scaffold site preview widget
simison Apr 28, 2026
30047ea
Full bleed activity feed
simison Apr 28, 2026
402ff28
Remove hello world
simison Apr 28, 2026
70aaa1c
Preview styles
simison Apr 28, 2026
af1f14b
Add scaffolding for site health widget
simison Apr 28, 2026
88444a4
Use design tokens for circle colors
simison Apr 28, 2026
95192d7
Add welcome to WP widget
simison Apr 30, 2026
447f558
Use UI components for welcome
simison Apr 30, 2026
2386be7
Welcome header updates
simison Apr 30, 2026
e9974ac
Add "edit site" to site preview
simison Apr 30, 2026
168a274
Scaffold news and events
simison Apr 30, 2026
9957ea3
Welcome: update styles
simison May 4, 2026
a63e3c2
Site preview: update styles
simison May 4, 2026
3ad7bf9
Site health: update styles
simison May 4, 2026
f326b0e
Quick draft: update styles
simison May 4, 2026
95fba93
Events-Newst: update styles
simison May 4, 2026
1d62ba9
Hello Dolly
simison May 5, 2026
159489a
Small design updates here and there
simison May 5, 2026
d5a3d60
Better empty state + loading indicator for activity
simison May 5, 2026
a09d0e1
Updates to health widget
simison May 5, 2026
248d3dc
Visually improved news and events widget
simison May 5, 2026
9700620
Better dates for events
simison May 5, 2026
35df869
Fix welcome card
simison May 5, 2026
e2fa271
Split events and news widgets to their own
simison May 5, 2026
7c8d734
Visual updates to welcome widget
simison May 5, 2026
fb0f710
Visual updates to events and news
simison May 5, 2026
21d96f2
Visual updates to events and news
simison May 5, 2026
846301b
Pass WP version to welcome widget dynamically
simison May 5, 2026
44021eb
Consistent core slug for widgets
simison May 5, 2026
88f8665
on this day widget
simison May 11, 2026
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
472 changes: 472 additions & 0 deletions lib/experimental/dashboard-widgets/class-gutenberg-on-this-day.php

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
class WP_Widget_Type {

/**
* Widget type key. Namespaced identifier, e.g. `core/hello-world`.
* Widget type key. Namespaced identifier, e.g. `core/on-this-day`.
*
* @var string
*/
Expand Down
15 changes: 9 additions & 6 deletions lib/experimental/dashboard-widgets/default-layout-seed.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
*/

/**
* Appends the bundled `core/hello-world` instance to the default layout
* Appends the bundled `core/on-this-day` instance to the default layout
* unless something earlier in the filter chain already added it.
*
* Only contributes to the bundled `gutenberg_dashboard` surface; other
Expand All @@ -30,16 +30,19 @@

$uuids = array_column( $dashboard_layout, 'uuid' );

if ( in_array( 'default-hello-world-widget-instance', $uuids, true ) ) {
if ( in_array( 'default-on-this-day-widget-instance', $uuids, true ) ) {
return $dashboard_layout;
}

$dashboard_layout[] = array(
'uuid' => 'default-hello-world-widget-instance',
'type' => 'core/hello-world',
'placement' => array(
'uuid' => 'default-on-this-day-widget-instance',

Check warning on line 38 in lib/experimental/dashboard-widgets/default-layout-seed.php

View workflow job for this annotation

GitHub Actions / PHP coding standards

Array double arrow not aligned correctly; expected 7 space(s) between "'uuid'" and double arrow, but found 8.
'type' => 'core/on-this-day',

Check warning on line 39 in lib/experimental/dashboard-widgets/default-layout-seed.php

View workflow job for this annotation

GitHub Actions / PHP coding standards

Array double arrow not aligned correctly; expected 7 space(s) between "'type'" and double arrow, but found 8.
'attributes' => array(
'windowDays' => 1,
),
'placement' => array(
'width' => 2,
'height' => 1,
'height' => 2,
),
);

Expand Down
198 changes: 198 additions & 0 deletions lib/experimental/dashboard-widgets/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,71 @@
*/

add_action( 'admin_menu', 'gutenberg_register_dashboard_widgets_menu' );
add_action( 'dashboard_init', 'gutenberg_dashboard_widgets_register_site_health_widget' );
add_action( 'dashboard-wp-admin_init', 'gutenberg_dashboard_widgets_register_site_health_widget' );
add_action( 'dashboard_init', 'gutenberg_dashboard_widgets_register_activity_widget' );
add_action( 'dashboard-wp-admin_init', 'gutenberg_dashboard_widgets_register_activity_widget' );
add_action( 'dashboard_init', 'gutenberg_dashboard_widgets_register_quick_draft_widget' );
add_action( 'dashboard-wp-admin_init', 'gutenberg_dashboard_widgets_register_quick_draft_widget' );
add_action( 'dashboard_init', 'gutenberg_dashboard_widgets_register_site_preview_widget' );
add_action( 'dashboard-wp-admin_init', 'gutenberg_dashboard_widgets_register_site_preview_widget' );
add_action( 'dashboard_init', 'gutenberg_dashboard_widgets_register_welcome_widget' );
add_action( 'dashboard-wp-admin_init', 'gutenberg_dashboard_widgets_register_welcome_widget' );
add_action( 'dashboard_init', 'gutenberg_dashboard_widgets_register_events_widget' );
add_action( 'dashboard-wp-admin_init', 'gutenberg_dashboard_widgets_register_events_widget' );
add_action( 'dashboard_init', 'gutenberg_dashboard_widgets_register_news_widget' );
add_action( 'dashboard-wp-admin_init', 'gutenberg_dashboard_widgets_register_news_widget' );
add_action( 'dashboard_init', 'gutenberg_dashboard_widgets_register_hello_dolly_widget' );
add_action( 'dashboard-wp-admin_init', 'gutenberg_dashboard_widgets_register_hello_dolly_widget' );
add_action( 'dashboard_init', 'gutenberg_dashboard_widgets_register_on_this_day_widget' );
add_action( 'dashboard-wp-admin_init', 'gutenberg_dashboard_widgets_register_on_this_day_widget' );
add_action( 'admin_print_scripts', 'gutenberg_dashboard_widgets_print_config' );

/**
* Prints dashboard widget frontend config for dashboard screens.
*/
function gutenberg_dashboard_widgets_print_config() {
$screen = get_current_screen();

if ( ! $screen ) {
return;
}

$is_dashboard_widgets_screen = in_array(
$screen->id,
array( 'dashboard', 'toplevel_page_dashboard-wp-admin' ),
true
);

if ( ! $is_dashboard_widgets_screen ) {
return;
}

$config = array(
'wpVersion' => explode( '-', wp_get_wp_version() )[0],
);
?>
<script>
window.wpDashboardWidgetsConfig = <?php echo wp_json_encode( $config ); ?>;
</script>
<?php
}

/**
* Wires the `site-health` widget as a dynamic dep of the dashboard module so it
* lands in the import map and React.lazy in the dashboard stage can resolve it.
*/
function gutenberg_dashboard_widgets_register_site_health_widget() {
$widget_module = 'wp/widgets/site-health/render';

if ( function_exists( 'gutenberg_register_dashboard_route' ) ) {
gutenberg_register_dashboard_route( '/__widget_site_health', $widget_module );
}

if ( function_exists( 'gutenberg_register_dashboard_wp_admin_route' ) ) {
gutenberg_register_dashboard_wp_admin_route( '/__widget_site_health', $widget_module );
}
}

/**
* Registers the Dashboard Widgets menu item.
Expand All @@ -21,3 +86,136 @@ function gutenberg_register_dashboard_widgets_menu() {
1
);
}


/**
* Wires the `site-preview` widget as a dynamic dep of the dashboard module so it
* lands in the import map and React.lazy in the dashboard stage can resolve it.
*/
function gutenberg_dashboard_widgets_register_site_preview_widget() {
$widget_module = 'wp/widgets/site-preview/render';

if ( function_exists( 'gutenberg_register_dashboard_route' ) ) {
gutenberg_register_dashboard_route( '/__widget_site_preview', $widget_module );
}

if ( function_exists( 'gutenberg_register_dashboard_wp_admin_route' ) ) {
gutenberg_register_dashboard_wp_admin_route( '/__widget_site_preview', $widget_module );
}
}

/**
* Wires the `quick-draft` widget as a dynamic dep of the dashboard module so it
* lands in the import map and React.lazy in the dashboard stage can resolve it.
*/
function gutenberg_dashboard_widgets_register_quick_draft_widget() {
$widget_module = 'wp/widgets/quick-draft/render';

if ( function_exists( 'gutenberg_register_dashboard_route' ) ) {
gutenberg_register_dashboard_route( '/__widget_quick_draft', $widget_module );
}

if ( function_exists( 'gutenberg_register_dashboard_wp_admin_route' ) ) {
gutenberg_register_dashboard_wp_admin_route( '/__widget_quick_draft', $widget_module );
}
}

/**
* Wires the `activity` widget as a dynamic dep of the dashboard module so it
* lands in the import map and React.lazy in the dashboard stage can resolve it.
*/
function gutenberg_dashboard_widgets_register_activity_widget() {
$widget_module = 'wp/widgets/activity/render';

if ( function_exists( 'gutenberg_register_dashboard_route' ) ) {
gutenberg_register_dashboard_route( '/__widget_activity', $widget_module );
}

if ( function_exists( 'gutenberg_register_dashboard_wp_admin_route' ) ) {
gutenberg_register_dashboard_wp_admin_route( '/__widget_activity', $widget_module );
}
}

/**
* Wires the `events` widget as a dynamic dep of the dashboard module so it
* lands in the import map and React.lazy in the dashboard stage can resolve it.
*/
function gutenberg_dashboard_widgets_register_events_widget() {
$widget_module = 'wp/widgets/events/render';

if ( function_exists( 'gutenberg_register_dashboard_route' ) ) {
gutenberg_register_dashboard_route( '/__widget_events', $widget_module );
}

if ( function_exists( 'gutenberg_register_dashboard_wp_admin_route' ) ) {
gutenberg_register_dashboard_wp_admin_route( '/__widget_events', $widget_module );
}
}

/**
* Wires the `news` widget as a dynamic dep of the dashboard module so it
* lands in the import map and React.lazy in the dashboard stage can resolve it.
*/
function gutenberg_dashboard_widgets_register_news_widget() {
$widget_module = 'wp/widgets/news/render';

if ( function_exists( 'gutenberg_register_dashboard_route' ) ) {
gutenberg_register_dashboard_route( '/__widget_news', $widget_module );
}

if ( function_exists( 'gutenberg_register_dashboard_wp_admin_route' ) ) {
gutenberg_register_dashboard_wp_admin_route( '/__widget_news', $widget_module );
}
}

/**
* Wires the `welcome` widget as a dynamic dep of the dashboard module so it
* lands in the import map and React.lazy in the dashboard stage can resolve it.
*/
function gutenberg_dashboard_widgets_register_welcome_widget() {
$widget_module = 'wp/widgets/welcome/render';

if ( function_exists( 'gutenberg_register_dashboard_route' ) ) {
gutenberg_register_dashboard_route( '/__widget_welcome', $widget_module );
}

if ( function_exists( 'gutenberg_register_dashboard_wp_admin_route' ) ) {
gutenberg_register_dashboard_wp_admin_route( '/__widget_welcome', $widget_module );

}
}

/**
* Wires the `hello-dolly` widget as a dynamic dep of the dashboard module so it
* lands in the import map and React.lazy in the dashboard stage can resolve it.
*/
function gutenberg_dashboard_widgets_register_hello_dolly_widget() {
$widget_module = 'wp/widgets/hello-dolly/render';

if ( function_exists( 'gutenberg_register_dashboard_route' ) ) {
gutenberg_register_dashboard_route( '/__widget_hello_dolly', $widget_module );
}

if ( function_exists( 'gutenberg_register_dashboard_wp_admin_route' ) ) {
gutenberg_register_dashboard_wp_admin_route( '/__widget_hello_dolly', $widget_module );
}
}

/**
* Wires the `on-this-day` widget as a dynamic dep of the dashboard module so it
* lands in the import map and React.lazy in the dashboard stage can resolve it.
*/
function gutenberg_dashboard_widgets_register_on_this_day_widget() {
$widget_module = 'wp/widgets/on-this-day/render';

if ( function_exists( 'gutenberg_register_dashboard_route' ) ) {
gutenberg_register_dashboard_route( '/__widget_on_this_day', $widget_module );
}

if ( function_exists( 'gutenberg_register_dashboard_wp_admin_route' ) ) {
gutenberg_register_dashboard_wp_admin_route(
'/__widget_on_this_day',
$widget_module
);
}
}
1 change: 1 addition & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -239,4 +239,5 @@ function gutenberg_is_experiment_enabled( $name ) {
require __DIR__ . '/experimental/dashboard-widgets/widget-types.php';
require __DIR__ . '/experimental/dashboard-widgets/dashboard-layout.php';
require __DIR__ . '/experimental/dashboard-widgets/default-layout-seed.php';
require __DIR__ . '/experimental/dashboard-widgets/class-gutenberg-on-this-day.php';
}
1 change: 1 addition & 0 deletions packages/private-apis/src/implementation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const CORE_MODULES_USING_PRIVATE_APIS = [
'@wordpress/global-styles-ui',
'@wordpress/ui',
'@wordpress/views',
'@wordpress/widgets',
];

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ const SAMPLE_LAYOUT: DashboardWidget[] = [
];

const DEFAULT_LAYOUT: DashboardWidget[] = [
{ uuid: 'default-hello-world-widget-instance', type: 'core/hello-world' },
{
uuid: 'default-on-this-day-widget-instance',
type: 'core/on-this-day',
attributes: { windowDays: 1 },
placement: { width: 2, height: 2 },
},
];

describe( 'useDashboardLayout', () => {
Expand Down
Loading
Loading