Skip to content

Feature/picasso modernization temp#4978

Draft
vedrani wants to merge 47 commits into
feature/pf-1992-migration-orchestratorfrom
feature/picasso-modernization-temp
Draft

Feature/picasso modernization temp#4978
vedrani wants to merge 47 commits into
feature/pf-1992-migration-orchestratorfrom
feature/picasso-modernization-temp

Conversation

@vedrani

@vedrani vedrani commented May 26, 2026

Copy link
Copy Markdown
Collaborator

[FX-NNNN]

Description

Describe the changes and motivations for the pull request.

How to test

  • Temploy
  • FIXME: Add the steps describing how to verify your changes

Screenshots

Before. After.
Insert screenshots or screen recordings Insert screenshots or screen recordings

Development checks

  • Add changeset according to guidelines (if needed)
  • Double check if picasso-tailwind-merge requires major update (check its README.md)
  • Read CONTRIBUTING.md and Component API principles
  • Make sure that additions and changes on the design follow Toptal's BASE design, and it's been already discussed with designers at #-base-core
  • Annotate all props in component with documentation
  • Create examples for component
  • Ensure that deployed demo has expected results and good examples
  • Ensure the changed/created components have not caused accessibility issues. How to use accessibility plugin in storybook.
  • Self reviewed
  • Covered with tests (visual tests included)

Breaking change

  • codemod is created and showcased in the changeset
  • test alpha package of Picasso in StaffPortal

All development checks should be done and set checked to pass the
GitHub Bot: TODOLess action

Alpha packages

Manually trigger the publish.yml workflow to publish alpha packages. Specify pull request number as a parameter (only digits, e.g. 123).

PR Review Guidelines

When to approve? ✅

You are OK with merging this PR and

  1. You have no extra requests.
  2. You have optional requests.
    1. Add nit: to your comment. (ex. nit: I'd rename this variable from makeCircle to getCircle)

When to request changes? ❌

You are not OK with merging this PR because

  1. Something is broken after the changes.
  2. Acceptance criteria is not reached.
  3. Code is dirty.

When to comment (neither ✅ nor ❌)

You want your comments to be addressed before merging this PR in cases like:

  1. There are leftovers like unnecessary logs, comments, etc.
  2. You have an opinionated comment regarding the code that requires a discussion.
  3. You have questions.

How to handle the comments?

  1. An owner of a comment is the only one who can resolve it.
  2. An owner of a comment must resolve it when it's addressed.
  3. A PR owner must reply with ✅ when a comment is addressed.

@changeset-bot

changeset-bot Bot commented May 26, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 10f00a2

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 86 packages
Name Type
@toptal/picasso-accordion Patch
@toptal/picasso-page Patch
@toptal/picasso-backdrop Patch
@toptal/picasso-badge Major
@toptal/picasso-container Patch
@toptal/picasso-drawer Minor
@toptal/picasso-dropdown Patch
@toptal/picasso-file-input Patch
@toptal/picasso-form-label Patch
@toptal/picasso-form-layout Patch
@toptal/picasso-form Patch
@toptal/picasso-grid Patch
@toptal/picasso-checkbox Major
@toptal/picasso-modal-context Patch
@toptal/picasso-modal Patch
@toptal/picasso-provider Minor
@toptal/picasso-popper Major
@toptal/picasso-note Patch
@toptal/picasso-notification Major
@toptal/picasso-outlined-input Patch
@toptal/picasso-charts Major
@toptal/picasso-menu Patch
@toptal/picasso-query-builder Patch
@toptal/picasso-rich-text-editor Major
@toptal/picasso-shared Patch
@toptal/picasso Patch
@toptal/picasso-forms Patch
@topkit/analytics-charts Patch
@toptal/picasso-account-select Patch
@toptal/picasso-alert Patch
@toptal/picasso-application-update-notification Patch
@toptal/picasso-autocomplete Patch
@toptal/picasso-avatar Patch
@toptal/picasso-button Patch
@toptal/picasso-calendar Patch
@toptal/picasso-carousel Patch
@toptal/picasso-date-picker Patch
@toptal/picasso-dropzone Patch
@toptal/picasso-empty-state Patch
@toptal/picasso-helpbox Patch
@toptal/picasso-input Patch
@toptal/picasso-input-adornment Patch
@toptal/picasso-list Patch
@toptal/picasso-number-input Patch
@toptal/picasso-overview-block Patch
@toptal/picasso-pagination Patch
@toptal/picasso-prompt-modal Patch
@toptal/picasso-quote Patch
@toptal/picasso-rating Patch
@toptal/picasso-section Patch
@toptal/picasso-select Patch
@toptal/picasso-tabs Patch
@toptal/picasso-timeline Patch
@toptal/picasso-tree-view Patch
@toptal/picasso-user-badge Patch
@toptal/picasso-radio Patch
@toptal/picasso-switch Patch
@toptal/picasso-tagselector Patch
@toptal/picasso-breadcrumbs Patch
@toptal/picasso-environment-banner Patch
@toptal/picasso-icons Patch
@toptal/picasso-link Patch
@toptal/picasso-loader Patch
@toptal/picasso-paper Patch
@toptal/picasso-slider Patch
@toptal/picasso-step Patch
@toptal/picasso-table Patch
@toptal/picasso-tag Patch
@toptal/picasso-tooltip Patch
@toptal/picasso-typography Patch
@toptal/picasso-utils Patch
@toptal/picasso-avatar-upload Patch
@toptal/picasso-password-input Patch
@toptal/picasso-timepicker Patch
@toptal/picasso-skeleton-loader Patch
@toptal/picasso-test-utils Patch
@toptal/picasso-pictograms Patch
@toptal/picasso-show-more Patch
@toptal/picasso-date-select Patch
@toptal/picasso-amount Patch
@toptal/picasso-collapse Patch
@toptal/picasso-fade Patch
@toptal/picasso-slide Patch
@toptal/picasso-typography-overflow Patch
@toptal/picasso-image Patch
@toptal/picasso-logo Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vedrani vedrani changed the base branch from master to feature/pf-1992-migration-orchestrator May 26, 2026 08:16
@github-actions

github-actions Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor
Fails
🚫

Commit 148040d does not meet requirements of Commit Message Quality:

  • title is too long (max 79 characters)
🚫

The pull request title is missing a Jira issue code. Correct format '[ASD-123] Add a cool feature'. If you're working without a Jira issue then add a 'no-jira' label to your pull request.

🚫 Please assign someone to this PR before merging.

Generated by 🚫 dangerJS against 10f00a2

@vedrani vedrani force-pushed the feature/picasso-modernization-temp branch from cf44677 to bdaa74e Compare May 28, 2026 08:20
@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request May 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request May 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request May 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request May 30, 2026
@vedrani vedrani force-pushed the feature/picasso-modernization-temp branch from 9e14fb4 to 4e352de Compare June 1, 2026 13:51
@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request Jun 3, 2026
@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request Jun 3, 2026
@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request Jun 3, 2026
@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request Jun 3, 2026
@vedrani vedrani force-pushed the feature/picasso-modernization-temp branch 2 times, most recently from ae31ce9 to a1b0b32 Compare June 5, 2026 07:18
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request Jun 8, 2026
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request Jun 9, 2026
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request Jun 9, 2026
@vedrani vedrani force-pushed the feature/picasso-modernization-temp branch from 04ba6c3 to fe18ec8 Compare June 10, 2026 10:34
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request Jul 8, 2026
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request Jul 8, 2026
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request Jul 8, 2026
* [PF-1994] Migrate Tooltip to @base-ui/react + Tailwind

Rebased onto latest feature/picasso-modernization-temp to pick up the Utils <->
picasso-tailwind-merge dependency wiring (commit 43c817d). Regenerated the
Tooltip and FileListItem jest snapshots for the rem-unit arrow, and the
pnpm-lock Tooltip importer. Cypress close assertions use should('not.exist')
to match @base-ui/react's unmount-on-close.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QTNVwrkXDV5qu3Ntv5u1vR

* Seat menu-item tooltip arrow on the option per design

A tooltip on a Menu.Item sat with the standard ~7px arrow gap, which in a
dense option list points the tip at the strip between rows and reads as
the wrong option. Per design (0-4px on menu items), menu-item anchors now
use a 0px tip gap so the arrow lands on the option it describes.

Scoped to `role="menuitem"` anchors, resolved lazily via base-ui's
sideOffset function (no extra state/render); every other tooltip is
unchanged. Autocomplete/Select options render in a Menu but as
`role="option"`, so they keep the standard gap.

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

* Express tooltip anchor gaps in rem for design patterns rule 7

The arrow/compact/follow-cursor gaps were raw px numbers. base-ui's
positioner needs a px number, so they now resolve from a rem source
(matching the file's existing spacingToPx idiom and the rem-sized arrow in
styles.ts) — values are unchanged (15/8/4/10px at the 16px root).

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

* Dismiss followCursor tooltip when the cursor roams far

base-ui's cursor tracking only repositions the popup; it never hides when
the pointer moves far from where the tooltip opened, so the popup lingered
under a distant cursor. Restore the legacy behavior (parity with the
removed use-tooltip-follow-cursor.ts): hide once the pointer moves past
50px from where the current move began, and reopen once it settles (250ms).
Scoped strictly to followCursor via a dedicated hidden-ref that also keeps
base-ui from re-opening mid-move; all other tooltips are untouched.

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

* Reserve tooltip gap as popup margin to fix Happo shadow crop

Happo sizes a DOM capture to the union of element BORDER boxes and does not
grow it for box-shadows. The migrated popup fitted tightly and was pushed
off the anchor with sideOffset, so every non-dropdown snapshot cropped
flush at the popup edge — ~13px short of the MUI baseline (the shadow band
below the popup was lost). MUI instead reserved the gap as the popup's own
`margin: 14px 0`, so its border box covered the gap band and the capture
kept the shadow strip.

Reproduce that: the popup carries the gap as a margin on the resolved-side
axis (my-/mx-[0.875rem], compact m-1), and sideOffset supplies only the
remainder (gap - margin) so the popup stays put — 0 for the standard arrow
gap, negative for the tighter menu-item seat. Verified via Happo Cypress vs
master: the 12 cropped variants now match pixel-perfect; only the
intentional inside-dropdown seat and sub-pixel residuals remain.

Also pin the Positioner anchor to the trigger's ref'd node (except
followCursor): base-ui otherwise anchors whichever element's handler
reported the open, so composite children (Radio/Checkbox: ref on the root
label, props on the inner control) jumped by the two nodes' rect delta
depending on interaction order. MUI always anchored the child's ref'd node.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Add @toptal/picasso-tailwind peer dependency to Tooltip

The migrated Tooltip renders className='z-tooltip', a utility that only
exists starting with the @toptal/picasso-tailwind minor this PR ships
(the tooltip z-index token changeset). Declare that requirement as a
peer (^4.1.0, caret style as Switch), and satisfy it locally with a
workspace devDependency: autoInstallPeers would otherwise try to fetch
the not-yet-published 4.1.0 from the registry and fail the install.

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

* Restore legacy tooltip open/close semantics in useTooltipState

Three related regressions of the hand-rolled controlled-open layer racing
base-ui, fixed cohesively:

- onOpen/onClose fired in handleOpenChange BEFORE the suppress/controlled
  gates decided whether to honor the request, so callbacks fired while the
  tooltip stayed closed — repeatedly, given base-ui's close/open churn. They
  now fire only after a request is honored, and only on a real closed-to-open
  or open-to-closed transition (legacy fired onOpen only past the
  ignoreOpening gate; base-ui's own hover timer no longer double-fires an
  already-open tooltip). The openRef updates eagerly so same-tick duplicate
  requests are deduped.

- handleTriggerMouseLeave never lifted the click-dismiss suppression (only a
  600ms timer that any open request cancelled did), so dismiss, leave,
  re-hover could stay stuck closed. Leaving the trigger now clears the
  suppression directly, as legacy handleMouseLeave cleared ignoreOpening —
  guarded by the trigger's bounding box, since a rounded trigger fires
  mouseleave while the pointer merely crosses its transparent corner pixels
  (verified by the Cypress boundary test). The timer machinery is gone.

- Click-to-open is again a touch-only affordance: the legacy handleClick
  opened on click solely for touch devices, while desktop opening is owned by
  hover + openDelay; and followCursor never opens on touch, matching
  @material-ui@5 (the deleted isTouchDevice guards). Touch detection reuses
  isPointerDevice from @toptal/picasso-utils, as before the migration.

New jest coverage: desktop click does not open, tap opens/closes on touch,
followCursor stays closed on touch, and dismiss-leave-rehover reopens.
Tests emit pointerdown before click - base-ui syncs closeOnClick from
onPointerDown, which jsdom's bare fireEvent.click never dispatches.

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

* Simplify tooltip sideOffset math where gap equals popup margin

In getPositionerOffsets the no-arrow branch is only reachable for compact
tooltips (followCursor returns earlier), so its gap and popup margin are
both 4px and the subtraction was always 0; likewise the standard arrow gap
was a pure alias of POPUP_MARGIN_PX, zeroing out against it. State that
directly: compact and standard arrow tooltips sit flush (only the user
offset remains) and a menu-item anchor shifts by its seat's difference
from the margin band. No behavioral change - every sideOffset resolves to
the same number as before, and the shadow-margin invariant is untouched.

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

* Document the fractional-rem tooltip arrow as a deliberate exception

The 0.71rem arrow box violates the whole-pixel styling rule, but no
whole-pixel construction can reproduce the required geometry: the
16px-base, 90-degree-apex triangle clipped from a 45-degree-rotated
square needs a side of 8*sqrt(2) (~11.314px, irrational), and the MUI
baseline itself rasterized at 0.71em = 11.36px - rounding moves the apex
and breaks the pixel match. Border-triangle and clip-path shapes cannot
carry the arrow's own box-shadow, and a drop-shadow filter would lose
the shadow band in Happo captures (bbox grows for box-shadow only).
Comment-only change.

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

* Restore MUI Grow open/close animation on the tooltip

The migrated popup appeared and vanished instantly; the JSS Tooltip
animated via TransitionComponent={Grow} (scale 0.75<->1 + fade, 200ms),
growing out of the anchor. base-ui exposes the transition through the
data-starting-style/data-ending-style attributes it sets on the popup and
the anchor-facing --transform-origin, so the popup class-builder now drives
the same Grow. Invisible to Happo: happoScreenshot waits for
data-starting-style to clear, so captures are the settled frame — verified
the Tooltip Cypress suite shows the same diff set (only the intentional
inside-dropdown seat + known sub-pixel residuals), no new diffs.

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

* [PF-1994] Migrate Tooltip to @base-ui/react + Tailwind

Tier 2 component. See PR description for prop-surface diff,
import diff, and Happo summary.

Refs: PF-1994

[review-iter 3] address review feedback

* Route consumer id to Tooltip popup, not the trigger

Legacy MUI put the id on the popper; base-ui spread it to the trigger via
...rest. Destructure id and pass it to Tooltip.Popup so it addresses the
popup (role=tooltip) as before. base-ui assigns the trigger its own
generated id.

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

* Extract Tooltip positioner geometry into utils.ts

Move splitPlacement, spacingToPxNumber, getPositionerOffsets and their gap
constants out of Tooltip.tsx into a co-located utils.ts, with a focused unit
test. Keeps them component-local for now; spacingToPxNumber and splitPlacement
are generic enough to graduate to picasso-shared when a second base-ui
positioned component needs them.

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

* Regroup Tooltip tests into when-context describe blocks

Restructure test.tsx and utils.test.ts into the house nested style
(describe subject -> describe 'when <condition>' -> it '<behavior>').
Behavior unchanged; snapshot keys follow the new describe paths.

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

* Fix tap-to-open on disabled-element tooltips (touch path)

A tap on a disabled control dispatches touch events but never a click
(the HTML spec bars disabled form controls from click events), so the
click-based tap-open path left 'tooltip on a disabled element' unopenable
by touch — a regression vs legacy. Add a touchstart-based open path that
reaches disabled anchors (mirroring the mouseover bubbling hover path),
with a touchOpenedRef dedupe so the trailing synthetic click on normal
elements doesn't toggle it straight back to click-to-dismiss.

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

* Fix touch tap-open: scroll discrimination and reopen latch

Two touch-interaction gaps in the tap-open path:
- A scroll/swipe that starts on the trigger opened a stuck tooltip
  (touchstart opened immediately; roam-close is mouse-only). Now the tap
  arms on touchstart and opens on touchend only within tap slop; a
  touchmove past 10px disarms it as a scroll.
- After a tap dismiss, suppressReopenRef was cleared only on mouseleave,
  which never fires on touch, so a fresh tap could not reopen. A tap that
  begins with the tooltip closed now lifts the latch (the touch analog of
  mouseleave).

Disabled-element tap-open is preserved (touch events fire on disabled
controls; only click is barred).

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

* Describe the tooltip trigger with the popup id while open

base-ui's Tooltip has no useRole, so it never sets aria-describedby on the
trigger the way legacy MUI did. With id routed to Tooltip.Popup, set
aria-describedby on the trigger to that id while open (falling back to any
consumer-supplied value when closed or without an id), restoring the
trigger-to-popup a11y link.

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

* [PF-1994] Migrate Tooltip to @base-ui/react + Tailwind

Tier 2 component. See PR description for prop-surface diff,
import diff, and Happo summary.

Refs: PF-1994

[cleanup] strip review-aid comments before merge

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request Jul 9, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request Jul 10, 2026
* Fix Modal/Drawer/Popper never rendering when open on first mount

usePicassoRoot() read rootRef.current during render, which is null on the
  tree's first render pass and never re-read (a ref mutation triggers no
  re-render). Modal, Drawer and Popper passed that null into Base UI /
  floating-ui portals, which treat an explicit null container as 'wait for
  the container to resolve' — so a mount-open overlay rendered nothing,
  forever. The pre-migration MUI Portal fell back to document.body instead.

  Two layers:

  - Provider: mirror the root node into React state via a callback ref and
    expose it through a dedicated PicassoRootNodeContext, so usePicassoRoot
    consumers re-render and receive the real node once it mounts — without
    re-rendering every RootContext consumer (titleCase etc.). rootRef stays
    on RootContext for backward compatibility.
  - Modal/Drawer/Popper: coerce an unresolved root to undefined instead of
    null so the portal degrades to document.body (MUI-era behavior).
    Drawer's disablePortal path keeps its intentional null (state-backed
    inline mount node).

  The stale PromptModal snapshot had the bug baked in (mount-open modal
  captured as an empty Picasso-root div); Modal snapshot ids shifted from
  the new test rendering earlier in the file.

* Resolve portal container fallback at the usePicassoRoot call sites

* Return undefined from usePicassoRoot instead of null

* Remove explanatory portal comment from Drawer

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request Jul 10, 2026
* Fix twMerge className prop position

* Revert some changes

* Fix tailwind short classes
@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request Jul 14, 2026
* [PF-2245] Keep tooltip open when clicked during hover-open delay

A click landing within the 200ms hover-open delay left the tooltip
permanently suppressed: base-ui opens synchronously on the mousedown-
focus, so the trailing click read that transient open and dismissed-
then-latched it shut, and the latch only clears on mouseleave (which
never fires while the cursor sits on the trigger). Every consumer
Cypress spec that clicks a tooltip trigger failed as a result.

Track whether the hover-open timer is still pending; a click in that
window lets the hover win instead of dismissing. A click after the
tooltip has deliberately opened still dismisses as before.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* [PF-2245] Simplify Tooltip open arbitration and drop redundant refs

Follow-up cleanup on the same file, no behavior change (23/23 unit
specs unchanged). base-ui's hover-open is rest-based, not the enter-
based delay MUI/legacy Picasso used, so Picasso runs its own hover
timer regardless. Vetoing base-ui's `trigger-hover` opens in
handleOpenChange makes Picasso the sole hover-open authority instead
of racing two differently-timed machines; base-ui keeps focus-open
and all dismissals.

Drop three redundant refs (11 -> 8):
- hoverOpenPendingRef: identical in lifetime to "openTimerRef has a
  pending timer"; the callback and every cancel path now null the
  timer id, so `openTimerRef.current !== undefined` is the pending
  signal the PF-2245 click guard reads.
- targetHoveredRef: mouseleave always clears the settle timer, so the
  reopen callback only fires while hovering -- the guard was always
  true.
- lastMoveEventRef: the settle timer is re-armed on every mousemove,
  so the callback's own closed-over event is the last move event.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request Jul 14, 2026
* [PF-1994] Tweak cypress transitions and wait logic

* [PF-1994] Cover more tests with wait logic

* [PF-1994] Tweak rest of cypress tests

* [PF-1994] Revert skipped tests

* [PF-1994] Tweak datepicker test

* [PF-1994] tweak fonts showing correctly test
@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request Jul 14, 2026
* [PF-2243] Fix Modal duplicate role attribute

* [PF-2243] Revert paper role overwrite
@github-actions

Copy link
Copy Markdown
Contributor

Picasso design patterns check failed

Rule Status
1 — Optimize defaults for the common case
2 — Reuse prop names across components
3 — Keep prop names short and simple
4 — Mirror native HTML prop names
5 — Style overrides only via className/style
6 — Prefer children over content props
7 — Use rem for all sizes ❌ RichTextEditor codeStyles/codeBlockStyles use raw px arbitrary values (text-[12px], leading-[18px])
8 — Align token names with BASE design system ❌ Same file swaps theme palette tokens for generic Tailwind colors (text-red-500, bg-gray-100)
9 — Use variant for visual variations
10 — Extend BaseProps
11 — Use as to change rendered element
12 — Use the shared size scale
13 — Use the shared color palette and shade scale
14 — No is prefix on boolean props
15 — Use compound components for multi-part components
16 — Use testIds for multi-part test selectors
F1 — Extends FieldProps (or descendant)
F2 — Honors the standard form-field props
F3 — Renders through PicassoField (or descendant)

@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

🚀 Your Storybook preview is ready: View Storybook

📍 Preview URL: https://toptal.github.io/picasso/prs/4978/

This preview is updated automatically when you push changes to this PR.

github-actions Bot added a commit that referenced this pull request Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants