1768 Commits

Author SHA1 Message Date
T. R. Bernstein
4a5f01a78f chore: Update code to new repo
Some checks failed
ci / changes (push) Has been cancelled
ci / lint (push) Has been cancelled
ci / build (push) Has been cancelled
ci / tests-unit (push) Has been cancelled
ci / tests-types (push) Has been cancelled
ci / int-cosmosdb (push) Has been cancelled
ci / int-documentdb (push) Has been cancelled
ci / int-firestore (push) Has been cancelled
ci / int-mongodb (push) Has been cancelled
ci / int-postgres (push) Has been cancelled
ci / int-postgres-custom-schema (push) Has been cancelled
ci / int-postgres-uuid (push) Has been cancelled
ci / int-sqlite (push) Has been cancelled
ci / int-sqlite-uuid (push) Has been cancelled
ci / int-supabase (push) Has been cancelled
ci / e2e-_community (push) Has been cancelled
ci / e2e-access-control (push) Has been cancelled
ci / e2e-admin-bar (push) Has been cancelled
ci / e2e-admin-root (push) Has been cancelled
ci / e2e-admin__e2e__document-view (push) Has been cancelled
ci / e2e-admin__e2e__general (push) Has been cancelled
ci / e2e-admin__e2e__list-view (push) Has been cancelled
ci / e2e-auth (push) Has been cancelled
ci / e2e-auth-basic (push) Has been cancelled
ci / e2e-bulk-edit (push) Has been cancelled
ci / e2e-field-error-states (push) Has been cancelled
ci / e2e-fields-relationship (push) Has been cancelled
ci / e2e-fields__collections__Array (push) Has been cancelled
ci / e2e-fields__collections__Blocks#config.blockreferences.ts (push) Has been cancelled
ci / e2e-fields__collections__Blocks (push) Has been cancelled
ci / e2e-fields__collections__Checkbox (push) Has been cancelled
ci / e2e-fields__collections__Collapsible (push) Has been cancelled
ci / e2e-fields__collections__ConditionalLogic (push) Has been cancelled
ci / e2e-fields__collections__CustomID (push) Has been cancelled
ci / e2e-fields__collections__Date (push) Has been cancelled
ci / e2e-fields__collections__Email (push) Has been cancelled
ci / e2e-fields__collections__Indexed (push) Has been cancelled
ci / e2e-fields__collections__JSON (push) Has been cancelled
ci / e2e-fields__collections__Number (push) Has been cancelled
ci / e2e-fields__collections__Point (push) Has been cancelled
ci / e2e-fields__collections__Radio (push) Has been cancelled
ci / e2e-fields__collections__Relationship (push) Has been cancelled
ci / e2e-fields__collections__Row (push) Has been cancelled
ci / e2e-fields__collections__Select (push) Has been cancelled
ci / e2e-fields__collections__Tabs (push) Has been cancelled
ci / e2e-fields__collections__Tabs2 (push) Has been cancelled
ci / e2e-fields__collections__Text (push) Has been cancelled
ci / e2e-fields__collections__UI (push) Has been cancelled
ci / e2e-fields__collections__Upload (push) Has been cancelled
ci / e2e-folders (push) Has been cancelled
ci / e2e-form-state (push) Has been cancelled
ci / e2e-group-by (push) Has been cancelled
ci / e2e-hooks (push) Has been cancelled
ci / e2e-i18n (push) Has been cancelled
ci / e2e-joins (push) Has been cancelled
ci / e2e-lexical__collections__LexicalHeadingFeature (push) Has been cancelled
ci / e2e-lexical__collections__LexicalJSXConverter (push) Has been cancelled
ci / e2e-lexical__collections__LexicalLinkFeature (push) Has been cancelled
ci / e2e-lexical__collections__Lexical__e2e__blocks#config.blockreferences.ts (push) Has been cancelled
ci / e2e-lexical__collections__Lexical__e2e__blocks (push) Has been cancelled
ci / e2e-lexical__collections__Lexical__e2e__main (push) Has been cancelled
ci / e2e-lexical__collections__OnDemandForm (push) Has been cancelled
ci / e2e-lexical__collections__RichText (push) Has been cancelled
ci / e2e-lexical__collections___LexicalFullyFeatured (push) Has been cancelled
ci / e2e-lexical__collections___LexicalFullyFeatured__db (push) Has been cancelled
ci / e2e-live-preview (push) Has been cancelled
ci / e2e-localization (push) Has been cancelled
ci / e2e-locked-documents (push) Has been cancelled
ci / e2e-plugin-cloud-storage (push) Has been cancelled
ci / e2e-plugin-form-builder (push) Has been cancelled
ci / e2e-plugin-import-export (push) Has been cancelled
ci / e2e-plugin-multi-tenant (push) Has been cancelled
ci / e2e-plugin-nested-docs (push) Has been cancelled
ci / e2e-plugin-seo (push) Has been cancelled
ci / e2e-query-presets (push) Has been cancelled
ci / e2e-sort (push) Has been cancelled
ci / e2e-trash (push) Has been cancelled
ci / e2e-uploads (push) Has been cancelled
ci / e2e-versions (push) Has been cancelled
ci / e2e-turbo-_community (push) Has been cancelled
ci / e2e-turbo-access-control (push) Has been cancelled
ci / e2e-turbo-admin-bar (push) Has been cancelled
ci / e2e-turbo-admin-root (push) Has been cancelled
ci / e2e-turbo-admin__e2e__document-view (push) Has been cancelled
ci / e2e-turbo-admin__e2e__general (push) Has been cancelled
ci / e2e-turbo-admin__e2e__list-view (push) Has been cancelled
ci / e2e-turbo-auth (push) Has been cancelled
ci / e2e-turbo-auth-basic (push) Has been cancelled
ci / e2e-turbo-bulk-edit (push) Has been cancelled
ci / e2e-turbo-field-error-states (push) Has been cancelled
ci / e2e-turbo-fields-relationship (push) Has been cancelled
ci / e2e-turbo-fields__collections__Array (push) Has been cancelled
ci / e2e-turbo-fields__collections__Blocks#config.blockreferences.ts (push) Has been cancelled
ci / e2e-turbo-fields__collections__Blocks (push) Has been cancelled
ci / e2e-turbo-fields__collections__Checkbox (push) Has been cancelled
ci / e2e-turbo-fields__collections__Collapsible (push) Has been cancelled
ci / e2e-turbo-fields__collections__ConditionalLogic (push) Has been cancelled
ci / e2e-turbo-fields__collections__CustomID (push) Has been cancelled
ci / e2e-turbo-fields__collections__Date (push) Has been cancelled
ci / e2e-turbo-fields__collections__Email (push) Has been cancelled
ci / e2e-turbo-fields__collections__Indexed (push) Has been cancelled
ci / e2e-turbo-fields__collections__JSON (push) Has been cancelled
ci / e2e-turbo-fields__collections__Number (push) Has been cancelled
ci / e2e-turbo-fields__collections__Point (push) Has been cancelled
ci / e2e-turbo-fields__collections__Radio (push) Has been cancelled
ci / e2e-turbo-fields__collections__Relationship (push) Has been cancelled
ci / e2e-turbo-fields__collections__Row (push) Has been cancelled
ci / e2e-turbo-fields__collections__Select (push) Has been cancelled
ci / e2e-turbo-fields__collections__Tabs (push) Has been cancelled
ci / e2e-turbo-fields__collections__Tabs2 (push) Has been cancelled
ci / e2e-turbo-fields__collections__Text (push) Has been cancelled
ci / e2e-turbo-fields__collections__UI (push) Has been cancelled
ci / e2e-turbo-fields__collections__Upload (push) Has been cancelled
ci / e2e-turbo-folders (push) Has been cancelled
ci / e2e-turbo-form-state (push) Has been cancelled
ci / e2e-turbo-group-by (push) Has been cancelled
ci / e2e-turbo-hooks (push) Has been cancelled
ci / e2e-turbo-i18n (push) Has been cancelled
ci / e2e-turbo-joins (push) Has been cancelled
ci / e2e-turbo-lexical__collections__LexicalHeadingFeature (push) Has been cancelled
ci / e2e-turbo-lexical__collections__LexicalJSXConverter (push) Has been cancelled
ci / e2e-turbo-lexical__collections__LexicalLinkFeature (push) Has been cancelled
ci / e2e-turbo-lexical__collections__Lexical__e2e__blocks#config.blockreferences.ts (push) Has been cancelled
ci / e2e-turbo-lexical__collections__Lexical__e2e__blocks (push) Has been cancelled
ci / e2e-turbo-lexical__collections__Lexical__e2e__main (push) Has been cancelled
ci / e2e-turbo-lexical__collections__OnDemandForm (push) Has been cancelled
ci / e2e-turbo-lexical__collections__RichText (push) Has been cancelled
ci / e2e-turbo-lexical__collections___LexicalFullyFeatured (push) Has been cancelled
ci / e2e-turbo-lexical__collections___LexicalFullyFeatured__db (push) Has been cancelled
ci / e2e-turbo-live-preview (push) Has been cancelled
ci / e2e-turbo-localization (push) Has been cancelled
ci / e2e-turbo-locked-documents (push) Has been cancelled
ci / e2e-turbo-plugin-cloud-storage (push) Has been cancelled
ci / e2e-turbo-plugin-form-builder (push) Has been cancelled
ci / e2e-turbo-plugin-import-export (push) Has been cancelled
ci / e2e-turbo-plugin-multi-tenant (push) Has been cancelled
ci / e2e-turbo-plugin-nested-docs (push) Has been cancelled
ci / e2e-turbo-plugin-seo (push) Has been cancelled
ci / e2e-turbo-query-presets (push) Has been cancelled
ci / e2e-turbo-sort (push) Has been cancelled
ci / e2e-turbo-trash (push) Has been cancelled
ci / e2e-turbo-uploads (push) Has been cancelled
ci / e2e-turbo-versions (push) Has been cancelled
ci / build-template-blank-mongodb (push) Has been cancelled
ci / build-template-website-mongodb (push) Has been cancelled
ci / build-template-with-payload-cloud-mongodb (push) Has been cancelled
ci / build-template-with-vercel-mongodb-mongodb (push) Has been cancelled
ci / build-template-plugin- (push) Has been cancelled
ci / build-template-with-postgres-postgres (push) Has been cancelled
ci / build-template-with-vercel-postgres-postgres (push) Has been cancelled
ci / tests-type-generation (push) Has been cancelled
ci / All Green (push) Has been cancelled
ci / Publish Canary (push) Has been cancelled
ci / analyze (push) Has been cancelled
publish-prerelease / publish-prerelease-${{ github.ref_name }}-${{ github.sha }} (push) Has been cancelled
lock-issues / lock_issues (push) Has been cancelled
stale / stale (push) Has been cancelled
audit-dependencies / audit (push) Has been cancelled
activity-notifications / run (push) Has been cancelled
2025-10-08 23:27:45 +02:00
T. R. Bernstein
cd301ea583 chore: Update package.json to new repo 2025-10-07 23:47:52 +02:00
Jarrod Flesch
c2fa6299ee fix(ui): update memory user when autoLogin enabled (#14018)
Fixes https://github.com/payloadcms/payload/issues/14005

When `autoLogin` is enabled, the Auth Provider's user in memory becomes
stale. This change ensures the user in memory stays up to date if
`autoLogin && !autoLogin.prefillOnly` is set.
2025-10-07 13:51:43 -04:00
Elliot DeNolf
c58d556343 chore(release): v3.59.0 [skip ci] 2025-10-07 10:18:21 -04:00
Jacob Fletcher
b09ae6772f feat: slug field (#14007)
Discussion #8859. Requires #14012.

Exports a new `slugField`. This is a wrapper around the text field that
you can drop into any field schema.

A slug is a unique, indexed, URL-friendly string that identifies a
particular document, often used to construct the URL of a webpage. Slugs
are a fundamental concept for seemingly every project.

Traditionally, you'd build this field from scratch, but there are many
edge cases and nice-to-haves to makes this difficult to maintain by
hand. For example, it needs to automatically generate based on the value
of another field, provide UI to lock and re-generate the slug on-demand,
etc.

Fixes #13938.

When autosave is enabled, the slug is only ever generated once after the
initial create, leading to single character, or incomplete slugs.

For example, it is expected that "My Title" → "my-title, however ends up
as "m".

This PR overhauls the field to feel a lot more natural. Now, we only
generate the slug through:
1. The `create` operation, unless the user has modified the slug
manually
2. The `update` operation, if:
  a. Autosave is _not_ enabled and there is no slug
b. Autosave _is_ enabled, the doc is unpublished, and the user has not
modified the slug manually

The slug should stabilize after all above criteria have been met,
because the URL is typically derived from the slug. This is to protect
modifying potentially live URLs, breaking links, etc. without explicit
intent.

This fix, along with all the other features, is now standardized behind
the new `slugField`:

```ts
import type { CollectionConfig } from 'payload'
import { slugField } from 'payload'

export const MyCollection: CollectionConfig = {
  // ...
  fields: [
   // ...
   slugField()
  ]
}
```

In the future we could also make this field smart enough to auto
increment itself when its generated slug is not unique.

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211513433305005
2025-10-07 10:15:45 -04:00
Jacob Fletcher
08f6d99e4b fix(ui): phantom fields when duplicating rows with rows (#14068)
Fixes #14032.

When duplicating arrays that contains nested arrays, the newly
duplicated row will include twice as many fields within the nested array
as the original.

This is because duplicated row ids don't match 1:1 with their parent's
`rows` property.

For example: `array.0.nestedArray.0.id` should match
`array.0.nestedArray.rows[0].id`.

The problem is that when we duplicate the row, we regenerate all nested
id fields, but we fail to sync them its corresponding row in its parent
field. When we go to build form state on the server, we build new fields
for this stale row. Then when we merge server form state back into local
state, those new fields are simply _merged_ with the local state without
replacing them.

This is how we determine whether local changes to a row took place while
a form state request was pending. It is important to prevent the merge
strategy from overriding your active changes.

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211543194775558
2025-10-06 16:11:12 +00:00
Patrik
394000d07c fix(ui): invalid time value error when document locking with autosave enabled (#14062)
### What?

Fixes "Invalid time value" error in the DocumentLocked modal when
displaying the last edited timestamp.

### Why?

The `formatDate` function was passing a timestamp number directly to
`Intl.DateTimeFormat().format()`, which expects a Date object. When
`updatedAt` is a number (timestamp), this causes an "Invalid time value"
error.

### How?

Wrap the date parameter with `new Date()` before passing it to
`Intl.DateTimeFormat().format()` to properly convert the timestamp to a
Date object.

Fixes #14016
2025-10-03 11:26:48 -07:00
Jacob Fletcher
ca3f054041 fix(next): force inactive live preview after passing conditions (#14048)
Follow-up to #14012.

Once live preview conditions have passed, it is jarring for the live
preview window to suddenly appear. It should be that, despite
preferences, if the live preview window did not _load_ active, then it
should not become active until the user explicitly toggles it on.

This is especially poor UX while creating a new doc. If the conditional
URL is based on a field that has't been filled yet, upon filling that
field (with autosave), live preview suddenly appears and the entire page
shifts mid-edit.

Before:


https://github.com/user-attachments/assets/0da75306-eed3-4a77-bc58-d8a8dd0254bf

After:


https://github.com/user-attachments/assets/c7918601-959d-4ac5-b168-066afc3d879d

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211534009142634
2025-10-03 17:09:02 +01:00
Sasha
cb7a24ad70 fix(ui): undefined access with polymorphic joins and fix joins test config (#14057)
Currently integration / e2e tests on `main` fail because of this PR
https://github.com/payloadcms/payload/pull/12738
2025-10-03 15:25:58 +00:00
Kamal
1e238828b0 fix(ui): popup list controls overlap with table in list view (#13967)
### What?
- Fixes an issue where the table header row was overlapping menu items
in the ListControls component.

### Why?
- The overlapping occurred because the table lacked proper stacking
context, causing z-index rules to affecting the visibility and usability
of menu items in the ListControls component rendered above the table.

### How?
- Added the CSS property isolation: isolate to the table styles. This
creates a new stacking context, ensuring that the table header does not
interfere with overlapping UI elements

### UI Changes:
Before:
<img width="1357" height="730" alt="image"
src="https://github.com/user-attachments/assets/703f7bbe-0cd7-4dfb-a584-a6436a0ea5d7"
/>

After:
<img width="1357" height="730" alt="image"
src="https://github.com/user-attachments/assets/927c904a-4423-420b-ad4d-0a3c4624b5ee"
/>

Fixes #13941 

<!--

Thank you for the PR! Please go through the checklist below and make
sure you've completed all the steps.

Please review the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository if you haven't already.

The following items will ensure that your PR is handled as smoothly as
possible:

- PR Title must follow conventional commits format. For example, `feat:
my new feature`, `fix(plugin-seo): my fix`.
- Minimal description explained as if explained to someone not
immediately familiar with the code.
- Provide before/after screenshots or code diffs if applicable.
- Link any related issues/discussions from GitHub or Discord.
- Add review comments if necessary to explain to the reviewer the logic
behind a change

### What?

### Why?

### How?

Fixes #

-->
2025-10-03 07:51:52 -07:00
Patrik
62fcf18cc3 fix(ui): upload dropzone error when collectionConfig is undefined (#14043)
### What?

Fixes a bug where dragging a file into an upload dropzone when the
drawer is closed throws an error: "Cannot read properties of undefined".

### Why?

The `collectionConfig` variable can be undefined when the drawer is not
opened, causing the code to fail when trying to access
`collectionConfig.upload?.displayPreview`.

### How?

Added optional chaining (`?.`) to safely access `collectionConfig`,
changing `collectionConfig.upload?.displayPreview` to
`collectionConfig?.upload?.displayPreview`.

Fixes #13999
2025-10-03 06:42:21 -07:00
Said Akhrarov
cd546b3125 feat(ui): add support for disabling join field row types (#12738)
### What?
This PR adds a new `admin.disableRowTypes` config to `'join'` fields
which hides the `"Type"` column from the relationship table.

### Why?
While the collection type column _can be_ helpful for providing
information, it's not always necessary and can sometimes be redundant
when the field only has a singular relationTo. Hiding it can be helpful
by removing visual noise and providing editors the data directly.

### How?
By threading `admin.disableRowTypes` directly to the `getTableState`
function of the `RelationshipTable` component.

**With row types** (via `admin.disableRowTypes: false | undefined` OR
default for polymorphic):

![image](https://github.com/user-attachments/assets/22b55477-cf56-4b0e-a845-e6f2b39efe3b)

**Without row types** (default for monomorphic):

![image](https://github.com/user-attachments/assets/3a2bb0ba-2d5e-4299-8689-249b2d3fefe2)
2025-10-03 11:10:10 +01:00
Jarrod Flesch
bffb9ef8b9 fix(ui): saving empty code editor throw error (#14019)
Fixes https://github.com/payloadcms/payload/issues/14006

When attempting to save an empty code editor an error would throw
because `value` was undefined.
2025-10-02 14:31:45 -07:00
Paul
d826159fc0 fix(ui): add support back for custom live preview components (#14037)
Fixes https://github.com/payloadcms/payload/issues/13308

Adds support for a custom live preview component back, we previously
supported this and it was allowed via the config types but it wasn't
being rendered.

Now we export the `useLivePreviewContext` hook and the original
`LivePreviewWindow` component too so that end users can wrap the live
preview functionality with anything custom that they may need
2025-10-02 15:09:15 -04:00
Valur Sverrisson
7088d25787 fix(translations): fixes to Icelandic translations (#14038)
### What?
Add various missing translations for Icelandic language and update some
of the current ones to be more human readable.

### Why?
To make it more useable in Icelandic
2025-10-02 16:54:57 +00:00
Jacob Fletcher
2be6bb3c3b feat(ui): live preview conditions (#14012)
Supports live preview conditions. This is essentially access control for
live preview, where you may want to restrict who can use it based on
certain criteria, such as the current user or document data.

To do this, simply return null or undefined from your live preview url
functions:

```ts
url: ({ req }) => (req.user?.role === 'admin' ? '/hello-world' : null)
```

This is also useful for pages which derive their URL from document data,
e.g. a slug field, do not attempt to render the live preview window
until the URL is fully formatted.

For example, if you have a page in your front-end with the URL structure
of `/posts/[slug]`, the slug field is required before the page can
properly load. However, if the slug is not a required field, or when
drafts and/or autosave is enabled, the slug field might not yet have
data, leading to `/posts/undefined` or similar.

```ts
url: ({ data }) => data?.slug ? `/${data.slug}` : null
```

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211513433305000
2025-10-02 10:24:11 -04:00
Patrik
537f58b4bc feat: adds disableGroupBy to fields admin props (#14017)
### What?

Adds a new `disableGroupBy` admin config property for fields to control
their visibility in the list view GroupBy dropdown.

### Why

Previously, the GroupByBuilder was incorrectly using `disableListFilter`
to determine which fields to show in the group-by dropdown.

### How

- Added new `disableGroupBy` property to the field admin config types.
- Updated `GroupByBuilder` to filter fields based on `disableGroupBy`
instead of `disableListFilter`

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211511898438807
2025-10-02 06:22:32 -07:00
Patrik
accd95ec8a fix(ui): array fields not respecting width styles in row layouts (#13986)
### What?

This PR applies `mergeFieldStyles` to the `ArrayFieldComponent`
component, ensuring that custom admin styles such as `width` are
correctly respected when Array fields are placed inside row layouts.

### Why?

Previously, Array fields did not inherit or apply their `admin.width`
(or other merged field styles). For example, when placing two array
fields side by side inside a row with `width: '50%'`, the widths were
ignored, causing layout issues.

### How?

- Imported and used `mergeFieldStyles` within `ArrayFieldComponent`.
- Applied the merged styles to the root `<div>` via the `style` prop,
consistent with how other field components (like `TextField`) handle
styles.

Fixes #13973 


---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211511898438801
2025-10-01 10:15:30 -07:00
Elliot DeNolf
209b1f151b chore(eslint): set reportUnusedDisableDirectives to error (#14011)
Sets `reportUnusedDisableDirectives: 'error'` in our eslint config. This
will error when `// eslint-disable-*` directives are unused. It will
also auto-fix if possible.
2025-10-01 10:56:12 -04:00
Elliot DeNolf
5b64e12c65 chore(release): v3.58.0 [skip ci] 2025-09-30 09:22:02 -04:00
Patrik
9248fc41e8 fix(ui): query preset where field not displaying array values (#13961)
### What?

Query preset WhereField component was not displaying array values
correctly. When using relationship fields with operators like "is in"
that accept multiple values, the array values were not being formatted
and displayed properly in the query preset modal.

### Why?

The original `renderCondition` function only handled single values and
date objects, but did not include logic for arrays. This caused
relationship fields with multiple selected values to either not display
correctly or throw errors when viewed in query preset modals.

### How?

- Added proper array detection with `Array.isArray()` in the
`renderCondition` function
- Created a reusable `formatValue` helper function that handles single
values, objects (dates), and arrays consistently
- For arrays, format each value and join with commas:
`operatorValue.map(formatValue).join(', ')`
- Enhanced `addListFilter` test helper to accept both single values
(`string`) and arrays (`string[]`) for relationship field testing


---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211334352350024
2025-09-29 13:10:24 -07:00
Alessio Gravili
41aa201f7b fix: ensure blocks filterOptions are awaited (#13960)
Fixes #13956
2025-09-29 17:48:30 +00:00
Jacob Fletcher
3c4f8a3508 fix(next): static live preview url corrupt after save (#13949)
As of #13631, statically defined live preview URLs become corrupt after
the first save.

For example, if you define your URL as a string like this:

```ts
import type { CollectionConfig } from 'payload'

const MyCollection: CollectionConfig = {
  // ...
  admin: {
    livePreview: {
      url: '/hello-world'
    }
  }
}
```

On initial load, the iframe's src will evaluate to `.../hello-world` as
expected, but from the first save onward, the url becomes
`.../undefined`.

This is because for statically defined URLs, the `livePreviewURL`
property does not exist on the response. Despite this, we set it into
state as undefined. This is true for both collections and globals.

Initially reported on Discord here:
https://discord.com/channels/967097582721572934/967097582721572937/1421166976113442847

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211478736160152
2025-09-26 21:23:04 +00:00
Patrik
ae34b6d6d1 fix(ui): move collection description below title in document view (#13946)
### What?

Moved description rendering from DocumentFields to DocumentHeader
component.

### List view

#### Before 
<img width="1315" height="696" alt="Screenshot 2025-09-26 at 10 12
14 AM"
src="https://github.com/user-attachments/assets/9c102f4b-ed71-4e3d-85d6-87464e6c8568"
/>

#### After
<img width="1647" height="762" alt="Screenshot 2025-09-26 at 1 24 12 PM"
src="https://github.com/user-attachments/assets/1c2f4eae-5bf8-43ad-af65-23f333b01ba8"
/>


### Document View

#### Before
<img width="1321" height="673" alt="Screenshot 2025-09-26 at 10 57
01 AM"
src="https://github.com/user-attachments/assets/3c6c7218-a8f6-4e52-af27-f0c4ffa0a6ef"
/>

#### After
<img width="1645" height="682" alt="Screenshot 2025-09-26 at 1 24 29 PM"
src="https://github.com/user-attachments/assets/1ac774c7-8820-4d41-afef-c60044383474"
/>


### Document Drawer

<img width="1631" height="631" alt="Screenshot 2025-09-26 at 1 24 49 PM"
src="https://github.com/user-attachments/assets/42285d23-a37d-4419-9644-f9c27358f2bf"
/>

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211478222789332
2025-09-26 12:15:45 -07:00
Elliot DeNolf
71c684e72e chore(release): v3.57.0 [skip ci] 2025-09-25 12:49:38 -04:00
Dan Ribbens
456e3d6459 revert: "feat: adds new experimental.localizeStatus option (#13207)" (#13928)
This reverts commit 0f6d748365.

# Conflicts:
#	docs/configuration/overview.mdx
#	docs/experimental/overview.mdx
#	packages/ui/src/elements/Status/index.tsx
2025-09-25 15:14:19 +00:00
Jacob Fletcher
f868ed981b fix(next): clear bfcache on forward/back (#13913)
Fixes #12914.

Using the forward/back browser navigation shows stale data from the
previous visit.

For example:
1. Visit the list view, imagine a document with a title of "123"
2. Navigate to that document, update the title to "456"
3. Press the "back" button in the browser
4. Page incorrectly shows "123"
5. Press the "forward" button in the browser
6. Page incorrectly shows "123"

This is because Next.js caches those pages in memory in their
[Client-side Router
Cache](https://nextjs.org/docs/app/guides/caching#client-side-router-cache).
This enables instant loads during forward and back navigation by
restoring the previously cached response instead of making a new
request—which also happens to be our exact problem. This bfcache-like
behavior is not able to be opted out of, even if the page requires
authentication, etc.

The [hopefully temporary] fix is to force the router to make a new
request on forward/back navigation. We can do this by listening to the
popstate event and calling `router.refresh()`. This does create a flash
of stale content, however, because the refresh takes place _after_ the
cache was restored. While not wonderful, this is targeted to
specifically the forward/back events, and it's technically not
duplicative as the restored cache never made a request in the first
place.

Without native support, I'm not sure how else we'd achieve this, as
there's not way to invalidate the list view from a deeply nested
document drawer, for example.

Before:


https://github.com/user-attachments/assets/751b33b2-1926-47d2-acba-b1d47df06a6d

After:


https://github.com/user-attachments/assets/fe71938a-5c64-4756-a2c7-45dced4fcaaa

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211454879207837
2025-09-24 23:08:49 +00:00
Alessio Gravili
7bbd07c4a5 fix(ui): opening relationship field with appearance: "drawer" inside rich text inline block closes drawer (#13830)
Previously, clicking on a relationship with `appearance: 'drawer'`
within a lexical inline block drawer would close both drawers, instead
of opening a new drawer to select the relationship document.

Fixes https://github.com/payloadcms/payload/issues/13778

## Before


https://github.com/user-attachments/assets/371619d2-c64b-4e12-b8f3-72ad599db5a9


## After


https://github.com/user-attachments/assets/a05b9338-3b1d-4b0c-b78c-8e6b3b57014c

## Technical Notes

The issue happened due to the [`ModalContainer`'s
onClick](https://github.com/faceless-ui/modal/blob/main/src/ModalContainer/index.tsx#L43)
function being triggered when mouseUp on the relationship field is
triggered.

**Causes issue**: MouseDown => drawer opens => mouseUp
**Does not cause issue**: MouseDown => MouseUp => drawer opens

This is why the previous `setTimeout()` fix worked: it delayed the
drawer opening until the mouseUp event occured. If you click very slow,
the issue could still happen though.

I was not able to figure out _why_ the `onClick` of the ModalContainer
is triggered.

## The Fix

This is the ModalProvider `onClick` handler:

```ts
(e: MouseEvent<HTMLElement>) => {
      if (closeOnBlur) closeAllModals();
      if (typeof onClick === 'function') onClick(e);
    },
```

The fix is to simply set `closeOnBlur` to `false`, so that
`closeAllModals` is no longer called.

I was not able to manually trigger the onClick event of the
`ModalProvider`. I figured that it is more often called by strange React
Components triggering events like maniacs (react-select) rather than
some genuine user action.

In case some piece of functionality somehow relied on this event being
triggered and then closing the modal, that piece of functionality could
manually call `closeModal()` or attach a custom `onClick` function to
the modal. That way, this mechanism will be run in a more deliberate,
expected way.


---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211375615406672
2025-09-24 17:45:36 -04:00
Alessio Gravili
bea77f2f24 refactor(richtext-lexical): new upload node design (#13901)
This changes the design of lexical upload nodes to better show the
actual media instead of the metadata.

## Updated Design


https://github.com/user-attachments/assets/49096378-35c2-4eb0-b4b6-5f138d49bdad

Light mode:

<img width="780" height="962" alt="Screenshot 2025-09-24 at 10 11 32@2x"
src="https://github.com/user-attachments/assets/7611e659-3914-46e9-9c8c-db88c180227b"
/>


## Previous Design

> Before:
> 
> <img width="1358" height="860" alt="Screenshot 2025-09-22 at 16 01
16@2x"
src="https://github.com/user-attachments/assets/7831761c-6c3c-4072-82ed-68b88e3842b7"
/>
> 
> After:
> 
> <img width="1776" height="1632" alt="Screenshot 2025-09-22 at 16 01
00@2x"
src="https://github.com/user-attachments/assets/b434b6d5-a965-4c2b-adba-c1bf2a3be4bc"
/>
> 
> 
>
https://github.com/user-attachments/assets/f2749a38-c191-4b50-a521-8f722ed42a8f
> 



---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211429812808983
2025-09-24 20:22:03 +00:00
Patrik
1d1240fd13 feat: adds admin.formatDocURL function to control list view linking (#13773)
### What?

Adds a new `formatDocURL` function to collection admin configuration
that allows users to control the linkable state and URLs of first column
fields in list views.

### Why?

To provide a way to disable automatic link creation from the first
column or provide custom URLs based on document data, user permissions,
view context, and document state.

### How?

- Added `formatDocURL` function type to `CollectionAdminOptions` that
receives document data, default URL, request context, collection slug,
and view type
- Modified `renderCell` to call the function when available and handle
three return types:
  - `null`: disables linking entirely
  - `string`: uses custom URL
  - other: falls back to no linking for safety
- Added function to server-only properties to prevent React Server
Components serialization issues
- Updated `DefaultCell` component to support custom `linkURL` prop


---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211211792037945
2025-09-24 12:20:54 -07:00
Patrik
512a8fa19f fix: server component readonly state issues with document locking (#13878)
### What?

Fixed two bugs with readonly state for server-rendered components (like
richtext fields and custom server fields):

1. Server components remained readonly after a user took over a locked
document
2. Server components were not readonly when viewing in "read only" mode
until page refresh

### Why?

Both issues stemmed from server-rendered components using their initial
readonly state that was baked in during server-side rendering, rather
than respecting dynamic readonly state changes:

1. **Takeover bug**: When a user took over a locked document,
client-side readonly state was updated but server components continued
using their initial readonly state because the server-side state wasn't
refreshed properly.

2. **Read-only view bug**: When entering "read only" mode, server
components weren't immediately updated to reflect the new readonly state
without a page refresh.

The root cause was that server-side `buildFormState` was called with
`readOnly: isLocked` during initial render, and individual field
components used this initial state rather than respecting dynamic
document-level readonly changes.

### How?

1. **Fixed race condition in `handleTakeOver`**: Made the function async
and await the `updateDocumentEditor` call before calling
`clearRouteCache()` to ensure the database is updated before page reload

2. **Improved editor comparison in `getIsLocked`**: Used `extractID()`
helper to properly compare editor IDs when the editor might be a
reference object

3. **Ensured cache clearing for all takeover scenarios**: Call
`clearRouteCache()` for both DocumentLocked modal and DocumentControls
takeovers to refresh server-side state

4. **Added Form key to force re-render**: Added `key={isLocked}` to the
Form component so it re-renders when the lock state changes, ensuring
all child components get fresh readonly state for both takeover and
read-only view scenarios


---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211373627247885
2025-09-24 12:11:10 -07:00
Jarrod Flesch
662bab25ae fix(ui): corrects url for publish specific url (#13922)
Fixes incorrect url string for the publish specific locale button.
2025-09-24 17:40:33 +00:00
Jarrod Flesch
fcb8b5a066 feat(plugin-multi-tenant): improves tenant assignment flow (#13881)
### Improved tenant assignment flow
This PR improves the tenant assignment flow. I know a lot of users liked
the previous flow where the field was not injected into the document.
But the original flow, confused many of users because the tenant filter
(top left) was being used to set the tenant on the document _and_ filter
the list view.

This change shown below is aiming to solve both of those groups with a
slightly different approach. As always, feedback is welcome while we try
to really make this plugin work for everyone.


https://github.com/user-attachments/assets/ceee8b3a-c5f5-40e9-8648-f583e2412199

Added 2 new localization strings:

```
// shown in the 3 dot menu
'assign-tenant-button-label': 'Assign Tenant',

// shown when needing to assign a tenant to a NEW document
'assign-tenant-modal-title': 'Assign "{{title}}"',
```

Removed 2 localization strings:
```
'confirm-modal-tenant-switch--body',
'confirm-modal-tenant-switch--heading'
```
2025-09-24 13:19:33 -04:00
Patrik
3f5c989954 fix(ui): array field state to return empty array instead of 0 (#11283)
### What?

This PR fixes an issue where empty array fields would return `0` instead
of an empty array `[]` in form state.

The issue was caused by `rows` being initialized as `undefined` within
the array field reducer.

As a result, `rows` did not exist on array field state when initial
state was empty.

This has been updated to initialize as an empty array (`rows: []`) to
ensure consistent behavior when using `getDataByPath`.

Fixes #10712 


---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211439284995184
2025-09-24 13:17:30 -04:00
Sasha
f980a86bd6 fix(db-sqlite): exists operator in createJSONQuery (#13907)
Fixes https://github.com/payloadcms/payload/issues/13882
2025-09-24 18:42:33 +03:00
Alessio Gravili
59414bd8f1 feat(richtext-lexical): support copy & pasting and drag & dopping files/images into the editor (#13868)
This PR adds support for inserting images into the rich text editor via
both **copy & paste** and **drag & drop**, whether from local files or
image DOM nodes.

It leverages the bulk uploads UI to provide a smooth workflow for:
- Selecting the target collection
- Filling in any required fields defined on the uploads collection
- Uploading multiple images at once

This significantly improves the UX for adding images to rich text, and
also works seamlessly when pasting images from external editors like
Google Docs or Microsoft Word.

Test pre-release: `3.57.0-internal.801ab5a`

## Showcase - drag & drop images from computer


https://github.com/user-attachments/assets/c558c034-d2e4-40d8-9035-c0681389fb7b

## Showcase - copy & paste images from computer


https://github.com/user-attachments/assets/f36faf94-5274-4151-b141-00aff2b0efa4

## Showcase - copy & paste image DOM nodes


https://github.com/user-attachments/assets/2839ed0f-3f28-4e8d-8b47-01d0cb947edc

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211217132290841
2025-09-24 15:04:46 +00:00
Jarrod Flesch
5c81342bce fix(ui): folder filters hidden behind results (#13908)
Fixes https://github.com/payloadcms/payload/issues/13886

Search filters would be hidden behind the table results. This PR adds
css to adjust the z-index of the searchbar when it has an active popup.
2025-09-23 12:24:06 -04:00
Jacob Fletcher
00a673e491 feat(next): regenerate live preview url on save (#13631)
Closes #12785.

Although your live preview URL can be dynamic based on document data, it
is never recalculated after initial mount. This means if your URL is
dependent of document data that was just changed, such as a "slug"
field, the URL of the iframe does not reflect that change as expected
until the window is refreshed or you navigate back.

This also means that server-side live preview will crash when your
front-end attempts to query using a slug that no longer exists. Here's
the general flow: slug changes, autosave runs, iframe refreshes (url has
old slug), 404.

Now, we execute your live preview function on submit within form state,
and the window responds to the new URL as expected, refreshing itself
without losing its connection.

Here's the result:


https://github.com/user-attachments/assets/7dd3b147-ab6c-4103-8b2f-14d6bc889625

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211094211063140
2025-09-23 09:37:15 -04:00
Alessio Gravili
d8dace6509 feat: conditional blocks (#13801)
This PR introduces support for conditionally setting allowable block
types via a new `field.filterOptions` property on the blocks field.

Closes the following feature requests:
https://github.com/payloadcms/payload/discussions/5348,
https://github.com/payloadcms/payload/discussions/4668 (partly)

## Example

```ts
fields: [
  {
      name: 'enabledBlocks',
      type: 'text',
      admin: {
        description:
          "Change the value of this field to change the enabled blocks of the blocksWithDynamicFilterOptions field. If it's empty, all blocks are enabled.",
      },
    },
    {
      name: 'blocksWithFilterOptions',
      type: 'blocks',
      filterOptions: ['block1', 'block2'],
      blocks: [
        {
          slug: 'block1',
          fields: [
            {
              type: 'text',
              name: 'block1Text',
            },
          ],
        },
        {
          slug: 'block2',
          fields: [
            {
              type: 'text',
              name: 'block2Text',
            },
          ],
        },
        {
          slug: 'block3',
          fields: [
            {
              type: 'text',
              name: 'block3Text',
            },
          ],
        },
      ],
    },
    {
      name: 'blocksWithDynamicFilterOptions',
      type: 'blocks',
      filterOptions: ({ siblingData: _siblingData, data }) => {
        const siblingData = _siblingData as { enabledBlocks: string }

        if (siblingData?.enabledBlocks !== data?.enabledBlocks) {
          // Just an extra assurance that the field is working as intended
          throw new Error('enabledBlocks and siblingData.enabledBlocks must be identical')
        }
        return siblingData?.enabledBlocks?.length ? [siblingData.enabledBlocks] : true
      },
      blocks: [
        {
          slug: 'block1',
          fields: [
            {
              type: 'text',
              name: 'block1Text',
            },
          ],
        },
        {
          slug: 'block2',
          fields: [
            {
              type: 'text',
              name: 'block2Text',
            },
          ],
        },
        {
          slug: 'block3',
          fields: [
            {
              type: 'text',
              name: 'block3Text',
            },
          ],
        },
      ],
    },
]
```


https://github.com/user-attachments/assets/e38a804f-22fa-4fd2-a6af-ba9b0a5a04d2

# Rationale

## Why not `block.condition`?

- Individual blocks are often reused in multiple contexts, where the
logic for when they should be available may differ. It’s more
appropriate for the blocks field (typically tied to a single collection)
to determine availability.
- Hiding existing blocks when they no longer satisfy a condition would
cause issues - for example, reordering blocks would break or cause block
data to disappear. Instead, this implementation ensures consistency by
throwing a validation error if a block is no longer allowed. This aligns
with the behavior of `filterOptions` in relationship fields, rather than
`condition`.

## Why not call it `blocksFilterOptions`?

Although the type differs from relationship fields, this property is
named `filterOptions` (and not `blocksFilterOptions`) for consistency
across field types. For example, the Select field also uses
`filterOptions` despite its type being unique.

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211334752795631
2025-09-22 14:20:25 -07:00
Patrik
82d98ab375 fix(ui): revert-to-published button showing on new drafts (#13897)
### What?

Hide the "**Revert to published**" button when creating a new draft that
has never been published.

### Why?

Previously, the button was visible on new drafts, which was confusing
because there was no published version to revert to.

### How?

Updated the revert button condition to also require `hasPublishedDoc`.
2025-09-22 12:07:57 -07:00
Alessio Gravili
66f5d1429d fix(richtext-lexical): richtext field duplicates description custom component (#13880)
The lexical field component was accidentally rendering the description
component twice.

Fixes https://github.com/payloadcms/payload/issues/13644
2025-09-22 14:39:55 -04:00
Alessio Gravili
228e8f281a fix: admin.hidden not respected for RSCs, render-field server function not respecting field-overrides client-side (#13869)
This PR fixes 2 issues:

- the `fieldConfig.admin.hidden` property had no effect for react server
components, because the RSC was returned before we're checking for
`admin.hidden` in RenderFields
- the `render-field` server function did not propagate fieldConfig
overrides to the clientProps. This means overriding `admin.Label` had no
effect

Adds e2e tests for both issues
2025-09-22 14:36:41 -04:00
Jens Becker
77cac30046 perf(ui): use select API in RelationshipProvider to speed up load times in RelationshipCell (#13832)
### What?
Optimize the `RelationshipProvider` to only select the `useAsTitle`
field when fetching documents via the REST API. This reduces payload
size and speeds up loading of the related document title in
the`RelationshipCell` in the table view.

### Why?
Previously, when a document had a relationship field, the full document
data was requested in the table view, even though the relationship cell
only shows the title in the UI. On large collections, this caused
unnecessary overhead and slower UI performance.

### How?
Applies a select to the REST API request made in the
`RelationshipProvider`, limiting the responses to the `useAsTitle` field
only.

### Notes
- I’m not entirely sure whether this introduces a breaking change. If it
does, could you suggest a way to make this behavior opt-in?
- For upload enabled collections, the full document must be requested,
because the relationship cell needs access to fields like `mimeType`,
`thumbailURL` etc.
- I hope we can find a way to get this merged. In the Payload projects I
work on, this change has significantly improved list view performance.


Similar to #13228
2025-09-19 11:20:55 -04:00
Alessio Gravili
1c89291fac feat(richtext-lexical): utility render lexical field on-demand (#13657)
## Why this exists

Lexical in Payload is a React Server Component (RSC). Historically that
created three headaches:

1. You couldn’t render the editor directly from the client.
2. Features like blocks, tables, upload and link drawers require the
server to know the shape of nested sub‑fields at render time. If you
tried to render on demand, the server didn’t know those schemas.
3. The rich text field is designed to live inside a Form. For simple use
cases, setting up a full form just to manage editor state was
cumbersome.

## What’s new

We now ship a client component, `<RenderLexical />`, that renders a
Lexical editor **on demand** while still covering the full feature set.
On mount, it calls a server action to render the editor on the server
using the new `render-field` server action. That server render gives
Lexical everything it needs (including nested field schemas) and returns
a ready‑to‑hydrate editor.

## Example - Rendering in custom component within existing Form

```tsx
'use client'

import type { JSONFieldClientComponent } from 'payload'

import { buildEditorState, RenderLexical } from '@payloadcms/richtext-lexical/client'

import { lexicalFullyFeaturedSlug } from '../../slugs.js'

export const Component: JSONFieldClientComponent = (args) => {
  return (
    <div>
      Fully-Featured Component:
      <RenderLexical
        field={{ name: 'json' }}
        initialValue={buildEditorState({ text: 'defaultValue' })}
        schemaPath={`collection.${lexicalFullyFeaturedSlug}.richText`}
      />
    </div>
  )
}
```

## Example - Rendering outside of Form, manually managing richText
values

```ts
'use client'

import type { DefaultTypedEditorState } from '@payloadcms/richtext-lexical'
import type { JSONFieldClientComponent } from 'payload'

import { buildEditorState, RenderLexical } from '@payloadcms/richtext-lexical/client'
import React, { useState } from 'react'

import { lexicalFullyFeaturedSlug } from '../../slugs.js'

export const Component: JSONFieldClientComponent = (args) => {
  const [value, setValue] = useState<DefaultTypedEditorState | undefined>(() =>
    buildEditorState({ text: 'state default' }),
  )

  const handleReset = React.useCallback(() => {
    setValue(buildEditorState({ text: 'state default' }))
  }, [])

  return (
    <div>
      Default Component:
      <RenderLexical
        field={{ name: 'json' }}
        initialValue={buildEditorState({ text: 'defaultValue' })}
        schemaPath={`collection.${lexicalFullyFeaturedSlug}.richText`}
        setValue={setValue as any}
        value={value}
      />
      <button onClick={handleReset} style={{ marginTop: 8 }} type="button">
        Reset Editor State
      </button>
    </div>
  )
}
```

## How it works (under the hood)

- On first render, `<RenderLexical />` calls the server function
`render-field` (wired into @payloadcms/next), passing a schemaPath.
- The server loads the exact field config and its client schema map for
that path, renders the Lexical editor server‑side (so nested features
like blocks/tables/relationships are fully known), and returns the
component tree.
- While waiting, the client shows a small shimmer skeleton.
- Inside Forms, RenderLexical plugs into the parent form via useField;
outside Forms, you can fully control the value by passing
value/setValue.

## Type Improvements

While implementing the `buildEditorState` helper function for our test
suite, I noticed some issues with our `TypedEditorState` type:
- nodes were no longer narrowed by their node.type types
- upon fixing this issue, the type was no longer compatible with the
generated types. To address this, I had to weaken the generated type a
bit.

In order to ensure the type will keep functioning as intended from now
on, this PR also adds some type tests

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211110462564644
2025-09-18 15:01:12 -07:00
Jarrod Flesch
667c4f1634 fix(ui): bulk upload with locale param (#13865)
Fixes https://github.com/payloadcms/payload/issues/13859

Attaches locale to bulk upload post requests.
2025-09-18 14:39:13 -04:00
Jacob Fletcher
42b5935772 chore: consolidate canAccessAdmin logic (#13849)
Consolidates the logic for admin access control for server functions,
etc. behind a standard `canAccessAdmin` function.
2025-09-18 09:35:33 -04:00
Jarrod Flesch
5241113809 fix(ui): respect editorOptions, prevent field from flashing on save (#13848)
Fixes https://github.com/payloadcms/payload/issues/13774

EditorOptions were not being respected properly. The fix for this was to
set the following on the Editor component:
```ts
  detectIndentation: false,
  insertSpaces: undefined,
  tabSize: undefined,
```

### Other fixes
This PR also fixed the flash when JSON fields were saved. It removed the
need for the `editorKey` which was causing the entire field to re-mount
when the json value changed. We had this work around so data could be
set externally and the height would be automatically calculated when the
editor mounted. But since the JSON value did not have a stable reference
there was no way for react to memoize it, so the key would change every
time the document was saved.

Now we pass down a `recalculatedHeightAt` which allows data to be edited
externally still, but tells the component to recalculate its height
without forcing the component to re-mount.
2025-09-17 15:28:56 -04:00
Jacob Fletcher
9a8e3f817f chore(deps): bump @faceless-ui/modal to v3.0.0 (#13842)
Installs
[@faceless-ui/modal@3.0.0](https://github.com/faceless-ui/modal/releases/tag/v3.0.0),
which now has React v19 stable listed as its peer deps. This will
prevent dependency mismatch errors when installing node modules as
`react@19.0.0-rc.0` is no longer expected.
2025-09-17 15:51:11 +00:00
Jarrod Flesch
33228d9014 fix(ui): set prefetch false on Link buttons (#13846)
Fixes https://github.com/payloadcms/payload/issues/13834

Brings back `prefetch={false}` from
https://github.com/payloadcms/payload/pull/9020/files#diff-a2b1253ad6d1c9dde331641afc52893d73be7d3449c25e44b81066a839fef85dR152

I believe the prop was mistakenly removed, this PR adds it back.
2025-09-17 15:50:20 +00:00
Elliot DeNolf
ae3b923139 chore(release): v3.56.0 [skip ci] 2025-09-17 09:31:12 -04:00