Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
453 changes: 451 additions & 2 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions projects/js-packages/grid/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
vendor/
6 changes: 6 additions & 0 deletions projects/js-packages/grid/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
28 changes: 28 additions & 0 deletions projects/js-packages/grid/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# @automattic/jetpack-grid

Internal, **private** port of WordPress core's `@wordpress/grid` (the drag-and-drop / resize
grid powering dashboard layouts). Consumed by `@automattic/jetpack-widget-dashboard` and the
Jetpack Premium Analytics dashboard route.

Consumed as **source** (`exports` → `./src/index.ts`); the host build (`wp-build`) compiles the
TypeScript and CSS modules. This package ships no build output.

## Provenance

Ported verbatim from [`WordPress/gutenberg`](https://github.com/WordPress/gutenberg) `packages/grid/src`
@ commit `8a40c807e86` (branch `refactor/wp-build-name-as-module-id`).

When core publishes `@wordpress/grid`, replace this package with the published dependency and
update the import name in consumers. Keep this README's commit reference updated when syncing.

### Local deviations from core

- `src/shared/drag-overlay-drop-animation.ts`: the default-cleanup call uses a `typeof` guard
instead of an optional call (`cleanupDefault?.()`). Jetpack type-checks with `tsgo`
(`@typescript/native-preview`), which rejects optional-calling a `void | CleanupFunction`
union; the guard is semantically identical and passes both `tsc` and `tsgo`.

## Privacy

`"private": true` in `package.json` + `composer.json` without `npmjs-autopublish`/`mirror-repo`
guarantees this package is never published to npm or mirrored to a standalone repo.
4 changes: 4 additions & 0 deletions projects/js-packages/grid/changelog/initial-version
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Initial version: private port of WordPress core's @wordpress/grid for dashboard layouts.
21 changes: 21 additions & 0 deletions projects/js-packages/grid/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "automattic/jetpack-js-grid",
"description": "Grid component with drag-and-drop reordering and resize for dashboard layouts. Internal port of @wordpress/grid until it is published.",
"type": "library",
"license": "GPL-2.0-or-later",
"require": {},
"repositories": [
{
"type": "path",
"url": "../../packages/*",
"options": {
"monorepo": true
}
}
],
"minimum-stability": "dev",
"prefer-stable": true,
"extra": {
"textdomain": "jetpack-grid"
}
}
17 changes: 17 additions & 0 deletions projects/js-packages/grid/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { makeBaseConfig, defineConfig } from 'jetpack-js-tools/eslintrc/base.mjs';

// `src/` is vendored verbatim from WordPress core's `@wordpress/grid`. These rules
// conflict with core's house style; turning them off keeps the port faithful and
// avoids churn on every upstream re-sync. Drop this once core publishes the package.
export default defineConfig( makeBaseConfig( import.meta.url ), {
rules: {
'react/jsx-no-bind': 'off',
'import/order': 'off',
'no-shadow': 'off',
'jsdoc/check-indentation': 'off',
'jsdoc/escape-inline-tags': 'off',
'jsdoc/require-description': 'off',
'jsdoc/require-param-description': 'off',
'jsdoc/require-returns': 'off',
},
} );
49 changes: 49 additions & 0 deletions projects/js-packages/grid/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "@automattic/jetpack-grid",
"version": "0.1.0-alpha",
"private": true,
"description": "Grid component with drag-and-drop reordering and resize for dashboard layouts. Internal port of @wordpress/grid until it is published.",
"license": "GPL-2.0-or-later",
"author": "Automattic",
"type": "module",
"sideEffects": [
"**/*.module.css"
],
"exports": {
".": {
"jetpack:src": "./src/index.ts",
"types": "./src/index.ts",
"import": "./src/index.ts",
"default": "./src/index.ts"
}
},
"main": "./src/index.ts",
"module": "./src/index.ts",
"types": "./src/index.ts",
"scripts": {
"typecheck": "tsgo --noEmit"
},
"dependencies": {
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@wordpress/compose": "7.46.0",
"@wordpress/element": "6.46.0",
"@wordpress/icons": "13.1.0",
"@wordpress/ui": "0.13.0",
"clsx": "^2.1.1"
},
"devDependencies": {
"@types/react": "^18.3.27",
"@types/react-dom": "^18.3.7",
"@typescript/native-preview": "7.0.0-dev.20260225.1",
"jetpack-js-tools": "workspace:*",
"react": "18.3.1",
"react-dom": "18.3.1",
"typescript": "5.9.3"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
}
99 changes: 99 additions & 0 deletions projects/js-packages/grid/src/dashboard-grid/grid-item.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
.item {
position: relative;
}

.item-content {
position: relative;
height: 100%;
}

.is-resizing {
overflow: visible;
z-index: 1;
}

.is-resizing .item-content {
position: relative;
z-index: 2;
overflow: visible;
}

/*
* During drag, the original item acts as a placeholder in its grid
* cell while `<DragOverlay>` renders a clone that follows the cursor.
* Fading the placeholder and outlining it makes the destination visible
* without any scaling or translation on the original element.
*
* Placeholder chrome waits until `data-wp-grid-dragging` is set and the
* drag-preview enter animation (`--wpds-motion-duration-sm`) finishes
* so the dashed outline does not flash under the lifting clone.
*/
.is-dragging {
pointer-events: none;
}

:global([data-wp-grid-dragging]) .is-dragging {
border-radius: var(--wp-grid-placeholder-radius, 0);
}

@media not (prefers-reduced-motion: reduce) {

:global([data-wp-grid-dragging]) .is-dragging {
opacity: 1;
outline-width: 0;
outline-style: var(--wp-grid-placeholder-outline-style, dashed);
outline-color: transparent;
animation:
wp-grid-item-placeholder-in 0ms linear
var(--wpds-motion-duration-sm) forwards;
}

@keyframes wp-grid-item-placeholder-in {

to {
opacity: var(--wp-grid-placeholder-opacity, 0.4);
outline-width: var(--wpds-border-width-sm);
outline-color: var(--wp-grid-placeholder-outline-color, var(--wpds-color-stroke-interactive-brand));
}
}
}

@media (prefers-reduced-motion: reduce) {

:global([data-wp-grid-dragging]) .is-dragging {
opacity: var(--wp-grid-placeholder-opacity, 0.4);
outline:
var(--wpds-border-width-sm)
var(--wp-grid-placeholder-outline-style, dashed)
var(--wp-grid-placeholder-outline-color, var(--wpds-color-stroke-interactive-brand));
}
}

@media (forced-colors: active) {

:global([data-wp-grid-dragging]) .is-dragging {
--wp-grid-placeholder-outline-color: Highlight;
}
}

.preview-overlay {
position: absolute;
top: 0;
inset-inline-start: 0;
box-sizing: border-box;
pointer-events: none;
z-index: 0;
border:
var(--wpds-border-width-sm)
var(--wp-grid-resize-preview-outline-style, solid)
var(--wp-grid-placeholder-outline-color, var(--wpds-color-stroke-interactive-brand));
background: transparent;
border-radius: var(--wp-grid-placeholder-radius, 0);
}

@media (forced-colors: active) {

.preview-overlay {
border-color: Highlight;
}
}
Loading
Loading