Skip to content

feat(playground): confirm Share on the button and explain the rest in a dialog - #643

Merged
javierbrea merged 6 commits into
feat/539/playgroundfrom
feat/539/playground-share-feedback
Nov 11, 2026
Merged

javierbrea merged 6 commits into
feat/539/playgroundfrom
feat/539/playground-share-feedback

Conversation

@javierbrea

@javierbrea javierbrea commented Nov 10, 2026 •

Copy link
Copy Markdown
Owner

Description

How Share tells its result, approved by the maintainer on a mockup (decision 25 of the playground plan). Part of #539, with no issue of its own.

What changes in the playground

  • A link that is copied turns Share into a check and Copied for 2 s, in the same color and at the same width. A visually hidden polite region says Link copied. The message next to Help is gone.
  • Every other outcome opens a dialog that stays until it is closed, with a ▲ or a ✕ before its title:
    • Long link copied, with the length of the link and the 8,192 limit.
    • The link could not be copied, when the browser refuses the clipboard. The link is in a read-only field, focused and selected, beside Close and Copy link, which copies again and turns into Copied as Share does. A failed retry selects the link again. For a link of more than 8,192 characters, the text adds the warning of Long link copied.
    • The link could not be made, when the store of the host fails to make it.
    • The project is too large for a link, with the limit it passes: 1,000 files and folders, 3,000 dependencies or 4 MiB of JSON.
    • The project cannot be shared, with the reason of the reader of links in a box.
  • The text and the reason of the dialog are its accessible description. The field or Got it takes the focus, and closing gives it back to Share.
  • A share whose link comes after a newer share no longer writes that older link to the clipboard.
  • The playground guide lists the dialogs, in docs/ and in the 7.4.1 snapshot (decision 20).

@boundaries/playground

  • ShareOutcome is a union of objects with a kind. failed splits into not-made and not-copied, which carries the link and, for a long link, its length (long), and too-large carries the limit and its maximum. readSketch and decodeHash return the limit they passed as tooLarge (nodes, dependencies or bytes) instead of true.
  • useShareLink returns the confirmation (isCopied), the notice and whether its dialog is open, and copyAgain with its own confirmation.
  • New elements: ui-kit/molecules/CopyButton (both faces in one grid cell), share/ui/atoms/CopiedAnnouncement, share/ui/molecules/ShareDialog and share/ui/helpers/shareNotice. ShareMessage and shareMessage are removed.
  • VISUALLY_HIDDEN, in the theme constants, serves the status of the top bar and the new region.
  • getStyle of shared/testing/emittedStyle reads the rules of a media query, for the reduced-motion transitions. .agents/rules/playground-testing.md limits emittedStyle to the rules that jsdom does not apply: on hover or focus, inside a media query, on a pseudo-element, and those that win by specificity. The page objects of the share dialog, the help dialog (counters and size) and the target row of the tree now read getComputedStyle, which jsdom gets right there.

Plan

  • Decision 25 records the change, and section 6 of 00-shared.md describes it. The mockup is not updated.
  • Step 8 of 10-e2e.md expects Share to read Copied.

For the reviewer

  • Under React's strict mode, which the harness uses, the focus trap of MUI runs its mount effect twice and hands the focus to the paper. So the dialog gives the focus to its first control again once it has entered, on top of autoFocus.
  • A notice stays after its dialog closes, so the content does not change while the dialog fades out.

Checks

  • pnpm nx check:all playground: 150 suites, 4936 tests, 100% coverage, and the build. pnpm nx run-many -t check:spell check:types lint -p website.
  • Chromium through the harness at 1280×800, in light and dark: Share and Copy link are 86.48 px wide in both faces. The regions say Link copied. In the not-copied dialog, the field has the focus with the whole link selected, also after a failed retry. Escape gives the focus back to Share.

Agreement

Please check the following boxes after you have read and understood each item.

🤖 Generated with Claude Code

javierbrea and others added 2 commits November 10, 2026 19:26
… a dialog

The result of Share was a small message next to Help, away from the
button and easy to miss. A link that is copied now turns Share into a
check and "Copied" for two seconds, at the same width, and a hidden live
region announces it. Any other outcome opens a dialog that stays until it
is closed: a long link, a link that the browser did not let the playground
copy (shown selected, with Copy link to try again), a link that could not
be made, and a project that is too large for a link (with the limit it
passes) or that the reader of links refuses (with its reason).

A share whose link comes after a newer share no longer writes it to the
clipboard. The playground guide describes the new feedback.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Decision 25, the Share line of the interface in 00-shared.md, and the
Share step of the e2e plan, which now expects the button to read Copied.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@javierbrea javierbrea added scope: documentation Improvements or additions to documentation scope: tests Improvements or additions to tests type: feature Feature to be implemented scope: code Changes in the funcional code of packages labels Nov 10, 2026
@javierbrea javierbrea self-assigned this Nov 10, 2026
@javierbrea
javierbrea marked this pull request as ready for review November 10, 2026 19:36

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

@coveralls

Copy link
Copy Markdown

Coverage Status

Coverage is 100.0% — feat/539/playground-share-feedback into feat/539/playground. No base build found for feat/539/playground.

4 similar comments
@coveralls

Copy link
Copy Markdown

Coverage Status

Coverage is 100.0% — feat/539/playground-share-feedback into feat/539/playground. No base build found for feat/539/playground.

@coveralls

Copy link
Copy Markdown

Coverage Status

Coverage is 100.0% — feat/539/playground-share-feedback into feat/539/playground. No base build found for feat/539/playground.

@coveralls

Copy link
Copy Markdown

Coverage Status

Coverage is 100.0% — feat/539/playground-share-feedback into feat/539/playground. No base build found for feat/539/playground.

@coveralls

Copy link
Copy Markdown

Coverage Status

Coverage is 100.0% — feat/539/playground-share-feedback into feat/539/playground. No base build found for feat/539/playground.

@coveralls

coveralls commented Nov 10, 2026 •

Copy link
Copy Markdown

Coverage Status

Coverage is 100.0% — feat/539/playground-share-feedback into feat/539/playground. No base build found for feat/539/playground.

@coveralls

Copy link
Copy Markdown

Coverage Status

Coverage is 100.0% — feat/539/playground-share-feedback into feat/539/playground. No base build found for feat/539/playground.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The PR does what its description says. Share confirms on the button at the same width, the Link copied region announces it and clears after 2 s, and each other outcome opens its dialog with the text of decision 25. The focus and the selection of the link behave as described, and closing gives the focus back to Share. An older share no longer copies its link once a newer one starts. The layering holds: CopyButton, CopiedAnnouncement, ShareDialog and shareNotice are in the right domain and sub-layer, the dialog state stays out of the store, and @boundaries/playground/share still loads in Node.js. pnpm nx check:all playground passes with 100% coverage, and both copies of the guide are updated.

Two non-blocking findings follow as inline comments: a long link whose copy fails never gets its warning, and a testing rule that no longer matches how emittedStyle is used.

Written by Devin

javierbrea and others added 4 commits November 11, 2026 06:49
…be copied

When the browser refused to copy a link of more than 8,192 characters,
the dialog offered the link to copy by hand or again but never said that
some apps may cut it. The not-copied outcome now carries the length of a
long link, and its dialog adds the warning of "Long link copied" after
its own text. The playground guide says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The testing rule limited emittedStyle to hover and focus, but the copy
button reads its prefers-reduced-motion rules with it. jsdom 26 applies
no rule inside a media query, does not weigh specificity and does not
compute pseudo-elements, so the rule now names those cases. The size of
the share dialog is computed by jsdom, so its page object reads it with
getComputedStyle.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e copied in the plan

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he page objects

The counters and the size of the help dialog and the outline of the
target row of the tree are computed by jsdom, so their page objects read
getComputedStyle instead of the rules. The footer spacing of the help
dialog keeps reading its rule: each element of the footer declares its
own margin after it, and jsdom, which does not weigh specificity, would
hide it. Its TSDoc says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Passed Quality Gate passed for 'javierbrea_eslint-plugin-boundaries_elements'

Issues
0 New issues
0 Accepted issues

Measures
0 Security Hotspots
0.0% Coverage on New Code
0.0% Duplication on New Code

See analysis details on SonarQube Cloud

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Passed Quality Gate passed for 'javierbrea_eslint-plugin-boundaries_config'

Issues
0 New issues
0 Accepted issues

Measures
0 Security Hotspots
0.0% Coverage on New Code
0.0% Duplication on New Code

See analysis details on SonarQube Cloud

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Passed Quality Gate passed for 'javierbrea_eslint-plugin-boundaries_policies'

Issues
0 New issues
0 Accepted issues

Measures
0 Security Hotspots
0.0% Coverage on New Code
0.0% Duplication on New Code

See analysis details on SonarQube Cloud

@sonarqubecloud

Copy link
Copy Markdown

@javierbrea
javierbrea merged commit 900caaf into feat/539/playground Nov 11, 2026
22 checks passed
javierbrea added a commit that referenced this pull request Nov 12, 2026
The website gets a playground at `/playground/`: sketch a project and its boundaries config, and see how each file is classified and which of its dependencies are allowed, evaluated in the browser by the same `@boundaries/config` and `@boundaries/policies` as the plugin. It was designed in [RFC #538](#538) and is tracked in #539 (milestone [Playground](https://github.com/javierbrea/eslint-plugin-boundaries/milestone/45)). Each part was reviewed in its own PR into `feat/539/playground`, listed below.

### For users

- The files of a project are sketched as a tree or as text, the `settings` and `rules` of `eslint.config.js` are written in a JSON5 editor that lints them, and dependencies are added through a picker and shown as import statements.
- Each dependency shows its verdict and the policy that decided it. The inspector describes the file and the dependency in focus as the selectors see them, and the problems panel lists the disallowed dependencies and the config errors.
- The evaluation runs in a web worker, so a slow project never blocks the page.
- A link holds the whole project, so it can be shared. The top bar has examples, Help, Reset and Share.
- The docs have a Playground guide and Open in playground buttons on the Quick start, the Overview, the Policies page and the `boundaries/dependencies` rule page, in `docs/` and in the 7.4.1 snapshot. The bug report template asks for a playground link.
- Desktop only: below 997 px the page shows a note and never loads the playground chunk.

### Projects

- `packages/playground` (`@boundaries/playground`, private): the component, host-agnostic through `ProjectSource` and `StateStore`, with the `/share` entry for the docs and the `/playwright` entry for browser specs. Its layering is lint-enforced; `packages/playground/AGENTS.md` and the `playground-components` and `playground-testing` rules describe it.
- `packages/website`: the page that hosts the playground in a lazy chunk, the `OpenInPlayground` docs component, the guide, its own Playwright page objects, and the changelog entries under `Unreleased`.
- `test/website-e2e` (new, private): a Playwright sanity suite of the production build in Chromium, at a desktop and a narrow viewport, in the `test-browsers` job of CI.
- Shared: the `playwright-testing` rule, `scripts/check-pom-parity.js` and `scripts/check-bundle-imports.js`, the fixed-wait lint of `support/eslint-config`, and the `build:playwright` and `check:pom-parity` targets.
- No published package changes: `elements`, `config`, `policies` and `eslint-plugin` are untouched.

### Pull requests

| PR | Issue | Change |
| --- | --- | --- |
| #599 | #551 | Scaffold the package and the website shell |
| #621 | #552 | M1: identify the files of a sketched project |
| #630 | #553 | M2: verdicts of the dependencies |
| #633 | #554 | M3: share by URL and embed in the docs |
| #637 | — | Scroll the inspector instead of cutting its lists |
| #638 | — | Describe the dependency in focus in the inspector |
| #641 | #635 | Evaluate the project in a web worker |
| #642 | #555 | Document the playground |
| #643 | — | Confirm Share on the button, explain the rest in a dialog |
| #644 | #634 | Raise the contrast of the text below 4.5:1 |
| #645 | #640 | Playwright page objects owned by the components |
| #646 | #640 | Check the website and the playground in Chromium |
| #648 | — | Remove the playground plan |

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: code Changes in the funcional code of packages scope: documentation Improvements or additions to documentation scope: tests Improvements or additions to tests type: feature Feature to be implemented

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants