PHPackages                             sugarcraft/candy-mouse - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. sugarcraft/candy-mouse

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

sugarcraft/candy-mouse
======================

Self-contained Mark/Scan/Get mouse hit-testing (bubblezone pattern) plus ZoneClickTracker for press/release deduplication. No external Manager wiring needed.

00PHP

Since Jun 1Pushed 1w agoCompare

[ Source](https://github.com/sugarcraft/candy-mouse)[ Packagist](https://packagist.org/packages/sugarcraft/candy-mouse)[ RSS](/packages/sugarcraft-candy-mouse/feed)WikiDiscussions master Synced 1w ago

READMEChangelogDependenciesVersions (1)Used By (0)

CandyMouse
==========

[](#candymouse)

Self-contained Mark/Scan/Get mouse hit-testing (bubblezone pattern) plus `ZoneClickTracker` for press/release deduplication. No external Manager wiring needed.

```
composer require sugarcraft/candy-mouse: dev-master

```

Role
----

[](#role)

Replaces the model where consumers wire `candy-zone`'s `Manager` externally. Each consumer owns its own `Scanner` instance — click handling stays local, no shared global state.

Quickstart
----------

[](#quickstart)

```
use SugarCraft\Mouse\Mark;
use SugarCraft\Mouse\Scanner;
use SugarCraft\Mouse\ZoneClickTracker;
use SugarCraft\Mouse\MouseEvent;

// 1. Wrap interactive content with invisible zone markers.
$rendered = Mark::zone('btn-ok', '  OK  ')
              . Mark::zone('btn-cancel', 'Cancel');

// 2. Scan after rendering to populate the zone registry.
$scanner = Scanner::new()->scan($rendered);

// 3. Reverse-lookup on mouse events.
$zone = $scanner->hit($mouseX, $mouseY); // ?Zone

// 4. Deduplicate clicks so each press+release pair emits one click.
$tracker = new ZoneClickTracker();
$result = $tracker->track(new MouseEvent(5, 1, 0, MouseAction::Release));
if ($result !== null) {
    echo "Clicked zone: " . $result->zone->id;
}
```

Key classes
-----------

[](#key-classes)

ClassRole`Mark`Wrap content with invisible Unicode sentinel markers`Scanner`Parse sentinels; `get(id)` and `hit(col, row)` lookups`Zone`Readonly bounding box (start/end col/row)`ZoneClickTracker`Press+Release dedup per button`MouseEvent`Immutable event (x, y, button, action enum)`MouseAction``Press` / `Release` / `Drag` / `Scroll` enumSentinel design
---------------

[](#sentinel-design)

Sentinels use private-use codepoints U+E000 (open) and U+E001 (close) — they never collide with ANSI SGR sequences or regular text. Scanning strips them from output.

Coverage
--------

[](#coverage)

[![codecov](https://camo.githubusercontent.com/1b2e3688c3922ee50ec0ddbad2e8007dc27463a72cffa1996f968553bb609623/68747470733a2f2f636f6465636f762e696f2f67682f737567617263726166742f63616e64792d6d6f7573652f6272616e63682f6d61737465722f67726170682f62616467652e7376673f666c61673d63616e64792d6d6f757365)](https://codecov.io/gh/sugarcraft/candy-mouse)

Upstream
--------

[](#upstream)

Inspired by [lrstanley/bubblezone](https://github.com/lrstanley/bubblezone) — the Mark/Scan/Get pattern mirrors bubblezone's API. `ZoneClickTracker` addresses [bubblezone issue #10](https://github.com/lrstanley/bubblezone/issues/10).

###  Health Score

20

—

LowBetter than 13% of packages

Maintenance64

Regular maintenance activity

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/b1036e0717211b8030b83cbe729e8ba6ba442fdbd5285fb97a39d7dcfe339342?d=identicon)[detain](/maintainers/detain)

---

Top Contributors

[![detain](https://avatars.githubusercontent.com/u/1364504?v=4)](https://github.com/detain "detain (6 commits)")

### Embed Badge

![Health badge](/badges/sugarcraft-candy-mouse/health.svg)

```
[![Health](https://phpackages.com/badges/sugarcraft-candy-mouse/health.svg)](https://phpackages.com/packages/sugarcraft-candy-mouse)
```

###  Alternatives

[antares/accessible-bundle

A bundle to easily use Accessible in Symfony projects.

153.8k](/packages/antares-accessible-bundle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
