Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
3bfc996
Remove dead legacy control panel scripts
brianjhanson Oct 28, 2026
7256c8f
Move Craft.LivePreview into the Yii2 adapter
brianjhanson Oct 28, 2026
51e9bc3
Split ported modules' Craft globals from their element registration
brianjhanson Oct 28, 2026
cc0968c
Publish Craft 6 control panel JS APIs from @craftcms/cp
brianjhanson Oct 28, 2026
45fd9b9
Publish the command palette API from @craftcms/cp
brianjhanson Oct 28, 2026
2a61e4c
Port Craft.Queue to a TypeScript PromiseQueue
brianjhanson Oct 28, 2026
9e25306
Move the relation field settings scripts into the Yii2 adapter
brianjhanson Oct 28, 2026
36e746f
Move Craft.js string and namespacing helpers to TypeScript
brianjhanson Oct 29, 2026
54ea4bb
Move Craft.js delta-data helpers to TypeScript
brianjhanson Oct 29, 2026
daad131
Move Craft.js URL helpers to TypeScript
brianjhanson Oct 29, 2026
50ab89d
Resolve drag handle selectors that start with a child combinator
brianjhanson Oct 29, 2026
8a37097
Use <craft-progress-bar> for asset field uploads
brianjhanson Oct 29, 2026
b9d7fd9
Merge remote-tracking branch 'origin/6.x' into chore/js-modules
brianjhanson Oct 29, 2026
17286eb
Stop rendering a legacy element index for element selector modals
brianjhanson Oct 29, 2026
92d71ad
Move the legacy element index renderer into the Yii2 adapter
brianjhanson Oct 29, 2026
f9d19c7
Move the legacy element index JavaScript into the Yii2 adapter
brianjhanson Oct 29, 2026
88cd64c
Move Craft.AdminTable into the Yii2 adapter
brianjhanson Oct 29, 2026
acbbd9f
Respect the category passed to Craft.t()
brianjhanson Oct 29, 2026
fd3add3
Translate control panel modules with t() instead of Craft.t()
brianjhanson Oct 29, 2026
4199492
Send control panel module requests with actionClient
brianjhanson Oct 29, 2026
aa679ce
Append server-rendered assets with @craftcms/ui's helpers
brianjhanson Oct 29, 2026
d6a786d
Move chip actions and attribute helpers to TypeScript
brianjhanson Oct 29, 2026
a2aa933
Read CP config and helpers from modules instead of Craft.*
brianjhanson Oct 30, 2026
2972a5c
Replace @craftcms/ui's factories with a typed create()
brianjhanson Oct 30, 2026
565faef
Move Craft.ui's field error and icon helpers to modules
brianjhanson Oct 30, 2026
0f7d3d6
Show CP messages with showNotice/showSuccess/showError
brianjhanson Oct 30, 2026
885dc81
Run the queue through QueueService instead of Craft.cp
brianjhanson Oct 30, 2026
81bd467
Load element thumbnails with loadElementThumbs()
brianjhanson Oct 30, 2026
8fb01be
Move the element clipboard from Craft.cp to a module
brianjhanson Oct 30, 2026
cbc9011
Announce through a module instead of Craft.cp
brianjhanson Oct 30, 2026
e5d2c76
Bind field toggles as they join the page; one entry point for initUiE…
brianjhanson Oct 30, 2026
47922d5
Read a switch's checked property in FieldToggle
brianjhanson Nov 2, 2026
8ca737a
Add a Link field to the workbench Page entry type
brianjhanson Nov 2, 2026
be1f743
Let action menus ask for an elevated session; drop formsubmit menus f…
brianjhanson Nov 2, 2026
ececd62
Stop core markup relying on Craft.initUiElements
brianjhanson Nov 2, 2026
9dcecb2
Merge remote-tracking branch 'origin/6.x' into chore/js-modules
brianjhanson Nov 2, 2026
4f4725e
Drop the removed html field from element selector test fixtures
brianjhanson Nov 2, 2026
2d5bb25
Import legacy-ui relatively, so the legacy bundle builds
brianjhanson Nov 2, 2026
cb9e4bc
Move Craft.ui into the Yii2 adapter
brianjhanson Nov 2, 2026
92e6ca6
Move Craft.ElementEditor into the Yii2 adapter
brianjhanson Nov 2, 2026
86c1175
Describe element action menu items instead of wiring them with inline JS
brianjhanson Nov 2, 2026
48cb1dd
Render control panel messages without Craft.CP.Notification
brianjhanson Nov 2, 2026
4dc90a7
Move Craft.CP into the Yii2 adapter
brianjhanson Nov 2, 2026
87b8a71
Move core's TypeScript off Craft.js helpers
brianjhanson Nov 2, 2026
4fa7b1c
Start the updater and focal point editor from modules
brianjhanson Nov 2, 2026
cbae1ef
Move Craft.js into the Yii2 adapter
brianjhanson Nov 2, 2026
b56e54d
Load Craft.js wherever plugins register CpAsset
brianjhanson Nov 2, 2026
7e24f28
Drop the legacy CP stylesheet, fonts and unused images
brianjhanson Nov 2, 2026
f7a34ca
Check for a legacy build that still exists before starting the dev se…
brianjhanson Nov 2, 2026
73ff86a
Fold the legacy cp bundle into cpcompat
brianjhanson Nov 2, 2026
08f9698
Load jQuery UI, jquery.payment, datepicker i18n and Picturefill from …
brianjhanson Nov 2, 2026
903c739
Import iframe-resizer in Live Preview; load Selectize from the adapter
brianjhanson Nov 2, 2026
c130124
Merge remote-tracking branch 'origin/6.x' into chore/js-modules
brianjhanson Nov 3, 2026
9c5bcf0
Merge remote-tracking branch 'origin/6.x' into chore/js-modules
brandonkelly Nov 4, 2026
3034d58
Stop the legacy FocalPointAsset registering a removed bundle
brandonkelly Nov 4, 2026
ed5b06a
Merge remote-tracking branch 'origin/6.x' into chore/js-modules
brianjhanson Nov 4, 2026
72a77dc
Merge remote-tracking branch 'origin/6.x' into chore/js-modules
brianjhanson Nov 4, 2026
8846cb3
Merge remote-tracking branch 'origin/6.x' into chore/js-modules
brianjhanson Nov 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .github/instructions/a11y.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ All graphics include `img`, `svg`, icon fonts, and emojis.
## Screen-reader-only text (MUST)

- Hide text that is only for assistive technology with the `sr-only` class, in Vue, PHP-rendered HTML, and Twig alike. It's defined in `packages/craftcms-ui/src/styles/cp.css` (and by Tailwind), which every control panel page loads.
- Do not use `visually-hidden`, even though older code does. It only exists in the legacy stylesheet (`packages/craftcms-legacy/cp/src/css/_main.scss`), which Inertia pages don't load, so the text shows on screen there.
- Do not use `visually-hidden`, even though older code does. Use `sr-only`, so there is one way to hide text visually.

## Live regions (MUST)

Expand Down
14 changes: 12 additions & 2 deletions CHANGELOG-WIP.md
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,6 @@
- `CraftCms\Cms\Cp\FormFields`
- `CraftCms\Cms\Cp\Html\ContentHtml`
- `CraftCms\Cms\Cp\Html\ElementHtml`
- `CraftCms\Cms\Cp\Html\ElementIndexHtml`
- `CraftCms\Cms\Cp\Html\MenuHtml`
- `CraftCms\Cms\Cp\Html\PreviewHtml`
- `CraftCms\Cms\Cp\Html\StatusHtml`
Expand Down Expand Up @@ -808,7 +807,7 @@ Craft 6 now uses [Laravel's authorization system](https://laravel.com/docs/12.x/
- Added `Cp.$assistant`, with `addContext()`, `removeContext()`, `getContext()`, `registerContextSource()`, and `registerTextExpander()` methods, for adding items to Ask AI’s context, its “Add context” menu, and text expanders in its message box. See `docs/ask-ai.md`. ([#20109](https://github.com/craftcms/cms/pull/20109))
- `<craft-action-menu>` now spaces `<hr>` elements in its slotted content as it does the dividers it renders from its `actions`. ([#20109](https://github.com/craftcms/cms/pull/20109))
- Added `CraftCms\Cms\Cp\CommandPalette\CommandPaletteItem`, `PageRegistry`, `ActionRegistry`, and `SearchProviderRegistry`, which plugins can use to add pages, actions, and search providers to the command palette, and `CraftCms\Cms\Cp\CommandPalette\Contracts\SearchProvider` and `CraftCms\Cms\Cp\CommandPalette\SearchProviders\ElementSearchProvider`, for searching custom content or element types. ([#20081](https://github.com/craftcms/cms/pull/20081))
- Added `Craft.commandPalette`, with `open()`, `close()`, `registerActions()`, `registerProvider()`, and `registerView()` methods, for opening the command palette and adding page actions, client-side search providers, and views to it. A page’s own action menus are listed as command palette actions when they’re within an element with a `data-command-palette-actions` attribute. ([#20081](https://github.com/craftcms/cms/pull/20081))
- Added `CommandPalette` to the `@craftcms/cp` import-map module, with `open()`, `close()`, `registerActions()`, `registerProvider()`, and `registerView()` methods, for opening the command palette and adding page actions, client-side search providers, and views to it. A page’s own action menus are listed as command palette actions when they’re within an element with a `data-command-palette-actions` attribute. ([#20081](https://github.com/craftcms/cms/pull/20081))
- Added a renderer-neutral control panel UI system with shared PHP and Vue rendering, extensible Nodes and Controls, nested and refreshable scopes, changed-only submission, and integration with configurable component settings, fields, and field layouts. ([#19384](https://github.com/craftcms/cms/pull/19384))
- Removed the `assets/upload` and `assets/replace-file` multipart endpoints and legacy uploader events and overrides, in favor of upload sessions. ([#19604](https://github.com/craftcms/cms/pull/19604))
- Removed HTMX from the control panel. Plugins that rely on it should bundle it themselves. ([#19836](https://github.com/craftcms/cms/pull/19836))
Expand Down Expand Up @@ -842,6 +841,17 @@ Craft 6 now uses [Laravel's authorization system](https://laravel.com/docs/12.x/
- Removed `Cp.$axios`.
- `Craft.Preview` is now only available when `craftcms/yii2-adapter` is installed, as a shim over Live Preview that fires Craft 5’s event names. Constructing it no longer creates a preview; `open()` goes to the element’s standalone preview page instead. `getActivePreview()` from `@craftcms/cp` should be used instead. ([#19964](https://github.com/craftcms/cms/pull/19964))
- Removed the `Craft.Accordion` and `Craft.EnvVarGenerator` control panel JavaScript classes. ([#19323](https://github.com/craftcms/cms/pull/19323))
- Removed the `Craft.ImageUpload` control panel JavaScript class.
- `Craft.AssetImageEditor`, `Craft.GroupedEntryTypeManager`, `Craft.RecoveryCodesSetup`, `Craft.SortableCheckboxSelect`, and `Craft.TagSelectInput` are now provided by the Yii2 adapter.
- The legacy element index is now rendered only by the Yii2 adapter, through the `elementIndex()` Twig function and `craft\helpers\Cp::elementIndexHtml()`. Templates that extend `_layouts/elementindex` always get the Vue element index.
- The legacy element index JavaScript is now provided by the Yii2 adapter: `Craft.createElementIndex()`, `Craft.registerElementIndexClass()`, `Craft.BaseElementIndex`, `Craft.BaseElementIndexView` and its subclasses, `Craft.AssetIndex`, `Craft.CategoryIndex`, `Craft.EntryIndex`, `Craft.UserIndex`, `Craft.Structure`, `Craft.StructureDrag`, `Craft.ProgressBar`, `Craft.ElementTableSorter`, `Craft.IntervalManager`, `Craft.PromptHandler`, and `Craft.openCustomizeSourcesModal()`.
- `Craft.AdminTable` and `Craft.DataTableSorter` are now provided by the Yii2 adapter.
- `Craft.ui` and `Craft.EditableTable` are now provided by the Yii2 adapter.
- `Craft.ElementEditor` and `Craft.ElementEditorSlideout` are now provided by the Yii2 adapter. Core’s element editors, slideouts included, all use the Vue editor.
- `Craft.CP` and `Craft.cp` are now provided by the Yii2 adapter. Control panel messages, the element clipboard and screen reader announcements no longer use them. `showNotice()`, `showSuccess()`, `showError()`, `copyElements()` and `announce()` are exported from `@craftcms/cp`.
- The legacy `Craft` helpers (`Craft.t()`, `Craft.sendActionRequest()`, `Craft.getUrl()`, `Craft.initUiElements()` and the rest of `Craft.js`), its jQuery plugins (`$.fn.disclosureMenu()`, `$.fn.menubtn()`, `$.fn.formsubmit()`…) and `Craft.queue` are now provided by the Yii2 adapter. Core uses `@craftcms/cp` and `@craftcms/ui` modules instead.
- Removed the `Craft.FocalPoint` and `Craft.Updater` control panel JavaScript classes. The image preview and the updater now start themselves from their markup.
- Added `AuthChallengeForm`, `AssetSelectorController`, `ElementSelectorController`, `Uploads`, `createElementSelectorModal`, `highlighter`, and `registerElementSelectorController` to the `@craftcms/cp` import-map module. Control panel plugin code should import them from there; they’re no longer `Craft.*` globals, except `Craft.createElementSelectorModal` and `Craft.highlighter`, which the Yii2 adapter still provides.
- Removed the classic (pre-3.2) `Craft.LivePreview` control panel JavaScript class, which Craft hasn’t used since 3.2. ([#19964](https://github.com/craftcms/cms/pull/19964))
- Deprecated the `Craft.LightSwitch`, `Craft.InfoIcon`, `Craft.ColorInput`, `Craft.PasswordInput`, `Craft.IconPicker`, `Craft.SlidePicker`, `Craft.SlideRuleInput`, and `Craft.Tooltip` control panel JavaScript classes, along with the `.infoicon` jQuery plugin. The corresponding `@craftcms/ui` web components should be used instead.
- Deprecated the `Craft.SortableCheckboxSelect` control panel JavaScript class. `<craft-checkbox-select>` should be used instead. ([#20036](https://github.com/craftcms/cms/pull/20036))
Expand Down
12 changes: 4 additions & 8 deletions docs/messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -352,20 +352,16 @@ window.dispatchEvent(
);
```

`Craft.cp.displayNotification()` still returns the `Craft.CP.Notification` instance, so existing
`Craft.cp.displayNotification()` (with the Yii2 adapter) still returns the notification, so existing
code that calls `.close()` or listens for `show` keeps working.

## The Default Display

The default display is the stack of messages in a corner of the screen. It's drawn by
`Craft.CP.Notification` (in `packages/craftcms-legacy/cp/src/js/CP.js`) into the `<cp-messages>`
element, and styled by `resources/css/messages.css`. It's modelled on
The default display is the stack of messages in a corner of the screen. Each message is a
`Notification` (`resources/js/modules/messages/notification.ts`), drawn into the `<cp-messages>`
element, which manages the stack, and styled by `resources/css/messages.css`. It's modelled on
[Sonner](https://sonner.emilkowal.ski).

> The renderer is still the legacy class because code holds on to the instance `display*()`
> returns (to call `.close()` or listen for `show`), and the "Entry copied." card extends it.
> Porting it is deferred; the queue in front of it doesn't depend on how it draws.

### Stacking

The newest message sits nearest the screen edge, with up to four more stacked behind it. Older
Expand Down
12 changes: 7 additions & 5 deletions docs/uploads.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,18 +139,20 @@ The contract has five methods:
- `complete()` verifies the stored bytes and returns an `UploadedFile` on the temporary disk. It must tolerate retries after storage completion.
- `abort()` removes incomplete transfers and completed temporary objects. It must tolerate retries.

Register the matching frontend transport in your plugin’s JavaScript, after the uploads entry has loaded. A plugin with a fixed endpoint only needs setup:
Register the matching frontend transport in your plugin’s JavaScript. In the control panel, import `Uploads` from `@craftcms/cp`. A plugin with a fixed endpoint only needs setup:

```js
Craft.Uploads.registerTransport('cloud', (uppy) => {
import {Uploads} from '@craftcms/cp';

Uploads.registerTransport('cloud', (uppy) => {
uppy.use(CloudUploadPlugin, {endpoint: '/cloud/upload'});
});
```

If configuration varies per file, return a preparation callback:

```js
Craft.Uploads.registerTransport('cloud', (uppy) => {
Uploads.registerTransport('cloud', (uppy) => {
uppy.use(CloudUploadPlugin);

return (fileId, {session}) => {
Expand Down Expand Up @@ -179,7 +181,7 @@ The registration callback configures one shared Uppy instance per transport. It

The request helper handles cancellation and normalizes backend errors; it only accepts same-origin URLs. Call `beginCompletion()` before an irreversible storage commit. Custom plugins advertise pause/resume support through Uppy’s `capabilities.resumableUploads` state and handle its per-file pause/resume events. Use the Uppy plugin lifecycle for transfer progress, failure, retry, and cancellation; Craft retains session creation and finalization. Uppy owns concurrency; queued files remain in the uploading state. Store session settings per file, since files with different destinations and headers share the instance.

`registerTransport` is also exported from `resources/js/uploads.ts`. The control panel exposes `Craft.Uploads` automatically; standalone pages must load the uploads entry. An existing registration can be replaced before its first use. Attempting to replace it after its Uppy instance has been created throws an error. An unregistered name fails explicitly.
Pages outside the control panel don’t have `@craftcms/cp`. They load the `resources/js/uploads.ts` entry and use `Craft.Uploads.registerTransport()` instead. An existing registration can be replaced before its first use. Attempting to replace it after its Uppy instance has been created throws an error. An unregistered name fails explicitly.

The shared transfer endpoint loads and locks the session, verifies ownership and expiry, and reauthorizes the destination before calling `handleRequest()`. It persists the uploader’s session changes afterward. DELETE requests are reserved for cleanup: ownership is still checked, but expiry and destination authorization are skipped. Uploaders must reject non-cleanup operations sent with DELETE. The S3 transport uses DELETE to request an abort signature and POST for other signatures. Frontend request helpers should pass `{signal: null}` for cleanup after cancellation.

Expand All @@ -189,7 +191,7 @@ Uploaders are cached by name. Keep upload-specific state on the session and reso

Craft handles session ownership and expiry; Uppy handles transfer retries and progress. The built-in tus endpoint supports HEAD, PATCH, termination, and expiration. Craft creates sessions through its JSON endpoints, so the tus creation extension is not exposed. The selected handler authorizes the destination and processes the completed file. The control panel exposes its native picker through `Craft.Uploaders.Uploader`. Core modules import `Uploader` from `resources/js/modules/uploader/uploader.ts`. Its constructor receives an `HTMLElement` and plain `UploaderSettings`; file inputs, drop zones, and paste zones accept native elements or arrays of elements. Completion and progress use the `on` callbacks.

Legacy uploader subclasses, filesystem-specific picker overrides, and jQuery upload events are no longer supported. Integrations customize file transfers through the backend uploader contract and `Craft.Uploads.registerTransport()`.
Legacy uploader subclasses, filesystem-specific picker overrides, and jQuery upload events are no longer supported. Integrations customize file transfers through the backend uploader contract and `Uploads.registerTransport()`.

## Migrating existing integrations

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
"@vueuse/shared": "^14.3.0",
"d3": "catalog:",
"fabric": "^7.4.0",
"iframe-resizer": "^4.4.5",
"laravel-vite-plugin": "^3.1.0",
"lit": "catalog:",
"overtype": "^2.4.0",
Expand Down
36 changes: 0 additions & 36 deletions packages/craftcms-legacy/cp/Ttf2Woff2Plugin.js

This file was deleted.

40 changes: 0 additions & 40 deletions packages/craftcms-legacy/cp/src/Craft.js

This file was deleted.

Loading
Loading