Skip to content

[6.x] Field slideout#19297

Merged
brandonkelly merged 25 commits into
6.xfrom
feature/field-slideout
Jul 23, 2026
Merged

[6.x] Field slideout#19297
brandonkelly merged 25 commits into
6.xfrom
feature/field-slideout

Conversation

@brianjhanson

Copy link
Copy Markdown
Contributor

A small-ish port focused on field settings slideout. Creates a few more PHP components (Input, Textbox and Icon) and then I took the opportunity to port Slideout and the sub classes over to our modern approach class + shim.

brianjhanson and others added 20 commits July 21, 2026 12:25
Add context about the PHP UI components
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The craft-action-item click bridge re-triggered `activate` on top of the
legacy Garnish `$.event.special.activate` synthesis, so jQuery-bound menu
item handlers (e.g. the field chip's Field settings slideout) ran twice.
Only bridge when the special event isn't registered.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Popper's fixed strategy writes viewport coordinates, but an ancestor that
forms a fixed-position containing block (transform, will-change, or the
slideout's container-type) rebases them onto itself, pushing the pane off
target. Measure where the pane actually landed after each write and
subtract the difference.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Replace action now announces via a bubbling, cancelable
`replace-component` event instead of calling the owning select's method
directly; the select's container listener provides the default (opening
the Choose menu, temporarily revealing it when hidden at the limit), and
wrappers can take the flow over with preventDefault().

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Lion pushes host properties onto the slotted control on upgrade
(LionInput/LionTextarea `updated()`), clobbering server-rendered
attributes with its defaults — placeholders vanished and input names were
wiped to empty. Non-default type/placeholder/name/disabled/readonly (and
rows for textareas) now render on the host too, which Lion then syncs
back onto the native control with the same values.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Matrix's expand/collapse/copy-all items (and Addresses' copy-all) operate
on the field's input, which isn't present where chips render (e.g. the
field layout designer's settings slideout). Craft 5 removed them at
runtime via the legacy disclosure-menu API, which the craft-action-menu
port no-ops; excluding them server-side with `showInChips` replaces that.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds an `ui('icon')` builder for `<craft-icon>` with legacy-alias/custom-
icon name resolution, a `data-color` palette setter, and a trusted inline
SVG slot. Also fixes `Icons::resolveIconData()` resolving the family from
the raw alias, which gave aliases pointing at custom icons (e.g. `move` →
`grip-dots`) the wrong family.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Callouts now always offer their variant-default icon unless `hide-icon`
opts out (mirrored on the Callout PHP component), and the field's
tip/warning notices lean on that default instead of overriding it,
announcing their prefix via craft-visually-hidden.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Field layout element indicators and chip icons now render through
craft-icon (via the new Icon builder on the PHP side), with data-color
driving the icon color — craft-icon maps it onto currentColor. Also
wraps the custom-field settings in a craft-field-group and tidies the
settings slideout spacing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The craft-input/craft-textarea components carry their own input chrome
now, so the legacy `.text` base/focus/sizing rules are no longer needed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`Craft.Slideout` is now a modern `@craftcms/garnish` `Base` class at
resources/js/modules/slideout, with the legacy global assigned via
`compatify()` so `Craft.CpScreenSlideout`'s legacy `.extend()` chain (and
`this.base()` dispatch) keeps working, and the static panel-stacking API
mirrored with shared in-place-mutated state. The public jQuery surface
(`$container` & co., `.data('slideout')`) survives for the subclass and
its consumers. Slideouts coordinate with the page's legacy
`uiLayerManager`/modal-background/HUD singletons when present, so Escape
handling and layer stacking stay unified with legacy modals and menus.

Since legacy bundles may evaluate before the Vite module assigns the
global, the three eval-time `Craft.Slideout.extend()` callers
(CpScreenSlideout, ElementEditorSlideout, AuthMethodSetup.Slideout) are
now built lazily on first access.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`Craft.CpScreenSlideout` is now a real TypeScript subclass of the modern
Slideout class, with the screen loading/update flow, tabs, sidebar, error
handling, and delta-aware submit ported intact and the jQuery surface
(`$content`, `$sidebar`, `data('cpScreen')`, …) preserved as public API.
The global stays `compatify()`-wrapped so `Craft.ElementEditorSlideout`'s
legacy `.extend()`/`this.base()` chain keeps dispatching into it.

Also reworks the module README into usage documentation and trims the
code comments down to current behavior and live constraints.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`Craft.ElementEditorSlideout` is now a real TypeScript subclass of
CpScreenSlideout, completing the slideout family; `Craft.ElementEditor`
remains a page-global seam, constructed on load with the slideout's
chrome handed in. All three slideout globals stay `compatify()`-wrapped
so plugin subclasses built on the legacy `.extend()` API keep working.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Moves the auth-method listing, its setup slideout (now a real TypeScript
subclass of Slideout — the last legacy `.extend()` in core), and the
recovery-codes flow into resources/js/modules/auth-method-setup, with the
stylesheet shipping in the CP bundles. Retires the authmethodsetup
webpack entry and the AuthMethodSetupAsset bundle registrations.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Legacy-rendered pages never called `Cp.config()`/`Cp.init()` (only
app.blade.php's Inertia boot did), leaving ConfigService, the queue,
translations, and the Wayfinder URL defaults uninitialized — so modern
modules like the elevated-session manager crashed on those surfaces.
legacy.ts now initializes the services from the `window.Craft` config
payload.

Also: ConfigService's URL helpers throw a descriptive error when the
service isn't initialized (instead of `new URL(undefined)`'s opaque
TypeError), its unused/ignored `getInstance()` parameter is gone, and
the elevated-session manager posts to the full action URL rather than a
bare action path actionClient's origin-only baseURL can't resolve.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The action client's baseURL was origin-only, so callers passing bare
action paths ('users/confirm-password', 'auth/verify-totp', …) produced
URLs missing the CP/action triggers and 404/405'd. The request
interceptor now resolves by shape: bare paths against the full action
base URL, /-prefixed (Wayfinder) route paths against the origin, and
absolute URLs untouched — fixing every bare-path caller (passkey login,
password reset, 2FA challenges, the API client) at the source. The
elevated-session manager's caller-side workaround is reverted
accordingly.

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

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown

📚 Storybook previews

@craftcms/uiopen Storybook

Changed components:

resources/jsopen Storybook

No changed components detected in this Storybook.

@brandonkelly
brandonkelly merged commit aae354d into 6.x Jul 23, 2026
26 checks passed
@brandonkelly
brandonkelly deleted the feature/field-slideout branch July 23, 2026 15:55
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.

2 participants