perf!: removes unnecessary field styles from initial page response (#9286)
Optimizes initial page responses by removing unnecessary inline field
styles that were being sent through the HTML response. The Client Config
contains a large number of duplicates of the string:
`"style\":{\"flex\":\"1 1 auto\"}`, one for every single field within
the entirely of the config. This leads to hundreds or potentially
thousands of instances of this same string, depending on the number of
fields within the config itself. This is regardless of custom field
widths being defined. Instead, we can do this entirely client-side,
preventing this string from ever being transmitted over the network in
the first place.
## Breaking Changes
This only effects those who are importing Payload's field components
into your own Custom Components or front-end application. The `width`
prop no longer exists. It has been consolidated into the existing
`style` prop. To migrate, simply move this prop as follows:
```diff
import { TextInput } from '@payloadcms/ui
export const MyCustomComponent = () => {
return (
<TextInput
- width="60%"
style={{
+ width: "60%,
}}
/>
)
}
```
This commit is contained in:
@@ -96,25 +96,6 @@ export const createClientField = ({
|
|||||||
clientField.label = incomingField.label({ t: i18n.t })
|
clientField.label = incomingField.label({ t: i18n.t })
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(clientField.admin instanceof Object)) {
|
|
||||||
clientField.admin = {} as AdminClient
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('admin' in incomingField && 'width' in incomingField.admin) {
|
|
||||||
clientField.admin.style = {
|
|
||||||
...clientField.admin.style,
|
|
||||||
'--field-width': clientField.admin.width,
|
|
||||||
}
|
|
||||||
|
|
||||||
delete clientField.admin.style.width // avoid needlessly adding this to the element's style attribute
|
|
||||||
} else {
|
|
||||||
if (!(clientField.admin.style instanceof Object)) {
|
|
||||||
clientField.admin.style = {}
|
|
||||||
}
|
|
||||||
|
|
||||||
clientField.admin.style.flex = '1 1 auto'
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (incomingField.type) {
|
switch (incomingField.type) {
|
||||||
case 'array':
|
case 'array':
|
||||||
case 'collapsible':
|
case 'collapsible':
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
import type { EditorState, SerializedEditorState } from 'lexical'
|
import type { EditorState, SerializedEditorState } from 'lexical'
|
||||||
|
|
||||||
import { FieldLabel, useEditDepth, useField, withCondition } from '@payloadcms/ui'
|
import { FieldLabel, useEditDepth, useField, withCondition } from '@payloadcms/ui'
|
||||||
import React, { useCallback } from 'react'
|
import { mergeFieldStyles } from '@payloadcms/ui/shared'
|
||||||
|
import React, { useCallback, useMemo } from 'react'
|
||||||
import { ErrorBoundary } from 'react-error-boundary'
|
import { ErrorBoundary } from 'react-error-boundary'
|
||||||
|
|
||||||
import type { SanitizedClientEditorConfig } from '../lexical/config/types.js'
|
import type { SanitizedClientEditorConfig } from '../lexical/config/types.js'
|
||||||
@@ -22,9 +23,10 @@ const RichTextComponent: React.FC<
|
|||||||
> = (props) => {
|
> = (props) => {
|
||||||
const {
|
const {
|
||||||
editorConfig,
|
editorConfig,
|
||||||
|
field,
|
||||||
field: {
|
field: {
|
||||||
name,
|
name,
|
||||||
admin: { className, readOnly: readOnlyFromAdmin, style, width } = {},
|
admin: { className, readOnly: readOnlyFromAdmin } = {},
|
||||||
label,
|
label,
|
||||||
localized,
|
localized,
|
||||||
required,
|
required,
|
||||||
@@ -87,15 +89,10 @@ const RichTextComponent: React.FC<
|
|||||||
[setValue],
|
[setValue],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const styles = useMemo(() => mergeFieldStyles(field), [field])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className={classes} key={pathWithEditDepth} style={styles}>
|
||||||
className={classes}
|
|
||||||
key={pathWithEditDepth}
|
|
||||||
style={{
|
|
||||||
...style,
|
|
||||||
width,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{Error}
|
{Error}
|
||||||
{Label || <FieldLabel label={label} localized={localized} required={required} />}
|
{Label || <FieldLabel label={label} localized={localized} required={required} />}
|
||||||
<div className={`${baseClass}__wrap`}>
|
<div className={`${baseClass}__wrap`}>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import type { ReactEditor } from 'slate-react'
|
|||||||
|
|
||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
import { FieldLabel, useEditDepth, useField, useTranslation, withCondition } from '@payloadcms/ui'
|
import { FieldLabel, useEditDepth, useField, useTranslation, withCondition } from '@payloadcms/ui'
|
||||||
|
import { mergeFieldStyles } from '@payloadcms/ui/shared'
|
||||||
import { isHotkey } from 'is-hotkey'
|
import { isHotkey } from 'is-hotkey'
|
||||||
import React, { useCallback, useEffect, useMemo, useRef } from 'react'
|
import React, { useCallback, useEffect, useMemo, useRef } from 'react'
|
||||||
import { createEditor, Node, Element as SlateElement, Text, Transforms } from 'slate'
|
import { createEditor, Node, Element as SlateElement, Text, Transforms } from 'slate'
|
||||||
@@ -19,8 +20,8 @@ import type { LoadedSlateFieldProps } from './types.js'
|
|||||||
import { defaultRichTextValue } from '../data/defaultValue.js'
|
import { defaultRichTextValue } from '../data/defaultValue.js'
|
||||||
import { richTextValidate } from '../data/validation.js'
|
import { richTextValidate } from '../data/validation.js'
|
||||||
import { listTypes } from './elements/listTypes.js'
|
import { listTypes } from './elements/listTypes.js'
|
||||||
import { hotkeys } from './hotkeys.js'
|
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
import { hotkeys } from './hotkeys.js'
|
||||||
import { toggleLeaf } from './leaves/toggle.js'
|
import { toggleLeaf } from './leaves/toggle.js'
|
||||||
import { withEnterBreakOut } from './plugins/withEnterBreakOut.js'
|
import { withEnterBreakOut } from './plugins/withEnterBreakOut.js'
|
||||||
import { withHTML } from './plugins/withHTML.js'
|
import { withHTML } from './plugins/withHTML.js'
|
||||||
@@ -42,9 +43,10 @@ declare module 'slate' {
|
|||||||
const RichTextField: React.FC<LoadedSlateFieldProps> = (props) => {
|
const RichTextField: React.FC<LoadedSlateFieldProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
elements,
|
elements,
|
||||||
|
field,
|
||||||
field: {
|
field: {
|
||||||
name,
|
name,
|
||||||
admin: { className, placeholder, readOnly: readOnlyFromAdmin, style, width } = {},
|
admin: { className, placeholder, readOnly: readOnlyFromAdmin } = {},
|
||||||
label,
|
label,
|
||||||
required,
|
required,
|
||||||
},
|
},
|
||||||
@@ -274,6 +276,8 @@ const RichTextField: React.FC<LoadedSlateFieldProps> = (props) => {
|
|||||||
// }
|
// }
|
||||||
// }, [path, editor]);
|
// }, [path, editor]);
|
||||||
|
|
||||||
|
const styles = useMemo(() => mergeFieldStyles(field), [field])
|
||||||
|
|
||||||
const classes = [
|
const classes = [
|
||||||
baseClass,
|
baseClass,
|
||||||
'field-type',
|
'field-type',
|
||||||
@@ -300,13 +304,7 @@ const RichTextField: React.FC<LoadedSlateFieldProps> = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className={classes} style={styles}>
|
||||||
className={classes}
|
|
||||||
style={{
|
|
||||||
...style,
|
|
||||||
width,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{Label || <FieldLabel label={label} required={required} />}
|
{Label || <FieldLabel label={label} required={required} />}
|
||||||
<div className={`${baseClass}__wrap`}>
|
<div className={`${baseClass}__wrap`}>
|
||||||
{Error}
|
{Error}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ export { getInitialColumns } from '../../elements/TableColumns/getInitialColumns
|
|||||||
export { Translation } from '../../elements/Translation/index.js'
|
export { Translation } from '../../elements/Translation/index.js'
|
||||||
export { withMergedProps } from '../../elements/withMergedProps/index.js' // cannot be within a 'use client', thus we export this from shared
|
export { withMergedProps } from '../../elements/withMergedProps/index.js' // cannot be within a 'use client', thus we export this from shared
|
||||||
export { WithServerSideProps } from '../../elements/WithServerSideProps/index.js'
|
export { WithServerSideProps } from '../../elements/WithServerSideProps/index.js'
|
||||||
|
export { mergeFieldStyles } from '../../fields/mergeFieldStyles.js'
|
||||||
export { reduceToSerializableFields } from '../../forms/Form/reduceToSerializableFields.js'
|
export { reduceToSerializableFields } from '../../forms/Form/reduceToSerializableFields.js'
|
||||||
export { PayloadIcon } from '../../graphics/Icon/index.js'
|
export { PayloadIcon } from '../../graphics/Icon/index.js'
|
||||||
export { PayloadLogo } from '../../graphics/Logo/index.js'
|
export { PayloadLogo } from '../../graphics/Logo/index.js'
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import type {
|
|||||||
CheckboxFieldValidation,
|
CheckboxFieldValidation,
|
||||||
} from 'payload'
|
} from 'payload'
|
||||||
|
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback, useMemo } from 'react'
|
||||||
|
|
||||||
import type { CheckboxInputProps } from './Input.js'
|
import type { CheckboxInputProps } from './Input.js'
|
||||||
|
|
||||||
@@ -17,8 +17,9 @@ import { useField } from '../../forms/useField/index.js'
|
|||||||
import { withCondition } from '../../forms/withCondition/index.js'
|
import { withCondition } from '../../forms/withCondition/index.js'
|
||||||
import { useEditDepth } from '../../providers/EditDepth/index.js'
|
import { useEditDepth } from '../../providers/EditDepth/index.js'
|
||||||
import { generateFieldID } from '../../utilities/generateFieldID.js'
|
import { generateFieldID } from '../../utilities/generateFieldID.js'
|
||||||
import { fieldBaseClass } from '../shared/index.js'
|
import { mergeFieldStyles } from '../mergeFieldStyles.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
import { fieldBaseClass } from '../shared/index.js'
|
||||||
import { CheckboxInput } from './Input.js'
|
import { CheckboxInput } from './Input.js'
|
||||||
|
|
||||||
const baseClass = 'checkbox'
|
const baseClass = 'checkbox'
|
||||||
@@ -30,14 +31,9 @@ const CheckboxFieldComponent: CheckboxFieldClientComponent = (props) => {
|
|||||||
id,
|
id,
|
||||||
checked: checkedFromProps,
|
checked: checkedFromProps,
|
||||||
disableFormData,
|
disableFormData,
|
||||||
|
field,
|
||||||
field: {
|
field: {
|
||||||
name,
|
admin: { className, description } = {} as CheckboxFieldClientProps['field']['admin'],
|
||||||
admin: {
|
|
||||||
className,
|
|
||||||
description,
|
|
||||||
style,
|
|
||||||
width,
|
|
||||||
} = {} as CheckboxFieldClientProps['field']['admin'],
|
|
||||||
label,
|
label,
|
||||||
required,
|
required,
|
||||||
} = {} as CheckboxFieldClientProps['field'],
|
} = {} as CheckboxFieldClientProps['field'],
|
||||||
@@ -85,6 +81,8 @@ const CheckboxFieldComponent: CheckboxFieldClientComponent = (props) => {
|
|||||||
|
|
||||||
const fieldID = id || generateFieldID(path, editDepth, uuid)
|
const fieldID = id || generateFieldID(path, editDepth, uuid)
|
||||||
|
|
||||||
|
const styles = useMemo(() => mergeFieldStyles(field), [field])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={[
|
className={[
|
||||||
@@ -97,10 +95,7 @@ const CheckboxFieldComponent: CheckboxFieldClientComponent = (props) => {
|
|||||||
]
|
]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(' ')}
|
.join(' ')}
|
||||||
style={{
|
style={styles}
|
||||||
...style,
|
|
||||||
width,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<RenderCustomComponent
|
<RenderCustomComponent
|
||||||
CustomComponent={Error}
|
CustomComponent={Error}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import type { CodeFieldClientComponent } from 'payload'
|
import type { CodeFieldClientComponent } from 'payload'
|
||||||
|
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback, useMemo } from 'react'
|
||||||
|
|
||||||
import { CodeEditor } from '../../elements/CodeEditor/index.js'
|
import { CodeEditor } from '../../elements/CodeEditor/index.js'
|
||||||
import { RenderCustomComponent } from '../../elements/RenderCustomComponent/index.js'
|
import { RenderCustomComponent } from '../../elements/RenderCustomComponent/index.js'
|
||||||
@@ -10,8 +10,9 @@ import { FieldError } from '../../fields/FieldError/index.js'
|
|||||||
import { FieldLabel } from '../../fields/FieldLabel/index.js'
|
import { FieldLabel } from '../../fields/FieldLabel/index.js'
|
||||||
import { useField } from '../../forms/useField/index.js'
|
import { useField } from '../../forms/useField/index.js'
|
||||||
import { withCondition } from '../../forms/withCondition/index.js'
|
import { withCondition } from '../../forms/withCondition/index.js'
|
||||||
import { fieldBaseClass } from '../shared/index.js'
|
import { mergeFieldStyles } from '../mergeFieldStyles.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
import { fieldBaseClass } from '../shared/index.js'
|
||||||
|
|
||||||
const prismToMonacoLanguageMap = {
|
const prismToMonacoLanguageMap = {
|
||||||
js: 'javascript',
|
js: 'javascript',
|
||||||
@@ -22,16 +23,9 @@ const baseClass = 'code-field'
|
|||||||
|
|
||||||
const CodeFieldComponent: CodeFieldClientComponent = (props) => {
|
const CodeFieldComponent: CodeFieldClientComponent = (props) => {
|
||||||
const {
|
const {
|
||||||
|
field,
|
||||||
field: {
|
field: {
|
||||||
name,
|
admin: { className, description, editorOptions = {}, language = 'javascript' } = {},
|
||||||
admin: {
|
|
||||||
className,
|
|
||||||
description,
|
|
||||||
editorOptions = {},
|
|
||||||
language = 'javascript',
|
|
||||||
style,
|
|
||||||
width,
|
|
||||||
} = {},
|
|
||||||
label,
|
label,
|
||||||
localized,
|
localized,
|
||||||
required,
|
required,
|
||||||
@@ -60,6 +54,8 @@ const CodeFieldComponent: CodeFieldClientComponent = (props) => {
|
|||||||
validate: memoizedValidate,
|
validate: memoizedValidate,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const styles = useMemo(() => mergeFieldStyles(field), [field])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={[
|
className={[
|
||||||
@@ -71,10 +67,7 @@ const CodeFieldComponent: CodeFieldClientComponent = (props) => {
|
|||||||
]
|
]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(' ')}
|
.join(' ')}
|
||||||
style={{
|
style={styles}
|
||||||
...style,
|
|
||||||
width,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<RenderCustomComponent
|
<RenderCustomComponent
|
||||||
CustomComponent={Label}
|
CustomComponent={Label}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import type { AdminClient, CollapsibleFieldClientComponent, DocumentPreferences } from 'payload'
|
import type { CollapsibleFieldClientComponent, DocumentPreferences } from 'payload'
|
||||||
|
|
||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
import React, { Fragment, useCallback, useEffect, useState } from 'react'
|
import React, { Fragment, useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
|
|
||||||
import { Collapsible as CollapsibleElement } from '../../elements/Collapsible/index.js'
|
import { Collapsible as CollapsibleElement } from '../../elements/Collapsible/index.js'
|
||||||
import { ErrorPill } from '../../elements/ErrorPill/index.js'
|
import { ErrorPill } from '../../elements/ErrorPill/index.js'
|
||||||
@@ -16,8 +16,9 @@ import { withCondition } from '../../forms/withCondition/index.js'
|
|||||||
import { useDocumentInfo } from '../../providers/DocumentInfo/index.js'
|
import { useDocumentInfo } from '../../providers/DocumentInfo/index.js'
|
||||||
import { usePreferences } from '../../providers/Preferences/index.js'
|
import { usePreferences } from '../../providers/Preferences/index.js'
|
||||||
import { useTranslation } from '../../providers/Translation/index.js'
|
import { useTranslation } from '../../providers/Translation/index.js'
|
||||||
import { fieldBaseClass } from '../shared/index.js'
|
import { mergeFieldStyles } from '../mergeFieldStyles.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
import { fieldBaseClass } from '../shared/index.js'
|
||||||
|
|
||||||
const baseClass = 'collapsible-field'
|
const baseClass = 'collapsible-field'
|
||||||
|
|
||||||
@@ -98,15 +99,12 @@ const CollapsibleFieldComponent: CollapsibleFieldClientComponent = (props) => {
|
|||||||
void fetchInitialState()
|
void fetchInitialState()
|
||||||
}, [getPreference, preferencesKey, fieldPreferencesKey, initCollapsed, path])
|
}, [getPreference, preferencesKey, fieldPreferencesKey, initCollapsed, path])
|
||||||
|
|
||||||
|
const styles = useMemo(() => mergeFieldStyles(field), [field])
|
||||||
|
|
||||||
if (typeof collapsedOnMount !== 'boolean') {
|
if (typeof collapsedOnMount !== 'boolean') {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const style: AdminClient['style'] = {
|
|
||||||
...field.admin?.style,
|
|
||||||
'--field-width': field.admin.width,
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<WatchChildErrors fields={fields} path={path.split('.')} setErrorCount={setErrorCount} />
|
<WatchChildErrors fields={fields} path={path.split('.')} setErrorCount={setErrorCount} />
|
||||||
@@ -120,7 +118,7 @@ const CollapsibleFieldComponent: CollapsibleFieldClientComponent = (props) => {
|
|||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(' ')}
|
.join(' ')}
|
||||||
id={`field-${fieldPreferencesKey}`}
|
id={`field-${fieldPreferencesKey}`}
|
||||||
style={style}
|
style={styles}
|
||||||
>
|
>
|
||||||
<CollapsibleElement
|
<CollapsibleElement
|
||||||
className={`${baseClass}__collapsible`}
|
className={`${baseClass}__collapsible`}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import type { DateFieldClientComponent, DateFieldValidation } from 'payload'
|
import type { DateFieldClientComponent, DateFieldValidation } from 'payload'
|
||||||
|
|
||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback, useMemo } from 'react'
|
||||||
|
|
||||||
import { DatePickerField } from '../../elements/DatePicker/index.js'
|
import { DatePickerField } from '../../elements/DatePicker/index.js'
|
||||||
import { RenderCustomComponent } from '../../elements/RenderCustomComponent/index.js'
|
import { RenderCustomComponent } from '../../elements/RenderCustomComponent/index.js'
|
||||||
@@ -12,16 +12,17 @@ import { FieldLabel } from '../../fields/FieldLabel/index.js'
|
|||||||
import { useField } from '../../forms/useField/index.js'
|
import { useField } from '../../forms/useField/index.js'
|
||||||
import { withCondition } from '../../forms/withCondition/index.js'
|
import { withCondition } from '../../forms/withCondition/index.js'
|
||||||
import { useTranslation } from '../../providers/Translation/index.js'
|
import { useTranslation } from '../../providers/Translation/index.js'
|
||||||
import { fieldBaseClass } from '../shared/index.js'
|
import { mergeFieldStyles } from '../mergeFieldStyles.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
import { fieldBaseClass } from '../shared/index.js'
|
||||||
|
|
||||||
const baseClass = 'date-time-field'
|
const baseClass = 'date-time-field'
|
||||||
|
|
||||||
const DateTimeFieldComponent: DateFieldClientComponent = (props) => {
|
const DateTimeFieldComponent: DateFieldClientComponent = (props) => {
|
||||||
const {
|
const {
|
||||||
|
field,
|
||||||
field: {
|
field: {
|
||||||
name,
|
admin: { className, date: datePickerProps, description, placeholder } = {},
|
||||||
admin: { className, date: datePickerProps, description, placeholder, style, width } = {},
|
|
||||||
label,
|
label,
|
||||||
localized,
|
localized,
|
||||||
required,
|
required,
|
||||||
@@ -52,6 +53,8 @@ const DateTimeFieldComponent: DateFieldClientComponent = (props) => {
|
|||||||
validate: memoizedValidate,
|
validate: memoizedValidate,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const styles = useMemo(() => mergeFieldStyles(field), [field])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={[
|
className={[
|
||||||
@@ -63,10 +66,7 @@ const DateTimeFieldComponent: DateFieldClientComponent = (props) => {
|
|||||||
]
|
]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(' ')}
|
.join(' ')}
|
||||||
style={{
|
style={styles}
|
||||||
...style,
|
|
||||||
width,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<RenderCustomComponent
|
<RenderCustomComponent
|
||||||
CustomComponent={Label}
|
CustomComponent={Label}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import type {
|
|||||||
} from 'payload'
|
} from 'payload'
|
||||||
|
|
||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback, useMemo } from 'react'
|
||||||
|
|
||||||
import { RenderCustomComponent } from '../../elements/RenderCustomComponent/index.js'
|
import { RenderCustomComponent } from '../../elements/RenderCustomComponent/index.js'
|
||||||
import { FieldDescription } from '../../fields/FieldDescription/index.js'
|
import { FieldDescription } from '../../fields/FieldDescription/index.js'
|
||||||
@@ -15,20 +15,19 @@ import { useField } from '../../forms/useField/index.js'
|
|||||||
import { withCondition } from '../../forms/withCondition/index.js'
|
import { withCondition } from '../../forms/withCondition/index.js'
|
||||||
import { useTranslation } from '../../providers/Translation/index.js'
|
import { useTranslation } from '../../providers/Translation/index.js'
|
||||||
import { FieldLabel } from '../FieldLabel/index.js'
|
import { FieldLabel } from '../FieldLabel/index.js'
|
||||||
import { fieldBaseClass } from '../shared/index.js'
|
import { mergeFieldStyles } from '../mergeFieldStyles.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
import { fieldBaseClass } from '../shared/index.js'
|
||||||
|
|
||||||
const EmailFieldComponent: EmailFieldClientComponent = (props) => {
|
const EmailFieldComponent: EmailFieldClientComponent = (props) => {
|
||||||
const {
|
const {
|
||||||
|
field,
|
||||||
field: {
|
field: {
|
||||||
name,
|
|
||||||
admin: {
|
admin: {
|
||||||
autoComplete,
|
autoComplete,
|
||||||
className,
|
className,
|
||||||
description,
|
description,
|
||||||
placeholder,
|
placeholder,
|
||||||
style,
|
|
||||||
width,
|
|
||||||
} = {} as EmailFieldClientProps['field']['admin'],
|
} = {} as EmailFieldClientProps['field']['admin'],
|
||||||
label,
|
label,
|
||||||
localized,
|
localized,
|
||||||
@@ -60,15 +59,14 @@ const EmailFieldComponent: EmailFieldClientComponent = (props) => {
|
|||||||
validate: memoizedValidate,
|
validate: memoizedValidate,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const styles = useMemo(() => mergeFieldStyles(field), [field])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={[fieldBaseClass, 'email', className, showError && 'error', readOnly && 'read-only']
|
className={[fieldBaseClass, 'email', className, showError && 'error', readOnly && 'read-only']
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(' ')}
|
.join(' ')}
|
||||||
style={{
|
style={styles}
|
||||||
...style,
|
|
||||||
width,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<RenderCustomComponent
|
<RenderCustomComponent
|
||||||
CustomComponent={Label}
|
CustomComponent={Label}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import type { GroupFieldClientComponent } from 'payload'
|
import type { GroupFieldClientComponent } from 'payload'
|
||||||
|
|
||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
import React from 'react'
|
import React, { useMemo } from 'react'
|
||||||
|
|
||||||
import { useCollapsible } from '../../elements/Collapsible/provider.js'
|
import { useCollapsible } from '../../elements/Collapsible/provider.js'
|
||||||
import { ErrorPill } from '../../elements/ErrorPill/index.js'
|
import { ErrorPill } from '../../elements/ErrorPill/index.js'
|
||||||
@@ -15,22 +15,19 @@ import { RenderFields } from '../../forms/RenderFields/index.js'
|
|||||||
import { useField } from '../../forms/useField/index.js'
|
import { useField } from '../../forms/useField/index.js'
|
||||||
import { withCondition } from '../../forms/withCondition/index.js'
|
import { withCondition } from '../../forms/withCondition/index.js'
|
||||||
import { useTranslation } from '../../providers/Translation/index.js'
|
import { useTranslation } from '../../providers/Translation/index.js'
|
||||||
|
import { mergeFieldStyles } from '../mergeFieldStyles.js'
|
||||||
import { useRow } from '../Row/provider.js'
|
import { useRow } from '../Row/provider.js'
|
||||||
import { fieldBaseClass } from '../shared/index.js'
|
import { fieldBaseClass } from '../shared/index.js'
|
||||||
import { useTabs } from '../Tabs/provider.js'
|
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
import { useTabs } from '../Tabs/provider.js'
|
||||||
import { GroupProvider, useGroup } from './provider.js'
|
import { GroupProvider, useGroup } from './provider.js'
|
||||||
|
|
||||||
const baseClass = 'group-field'
|
const baseClass = 'group-field'
|
||||||
|
|
||||||
export const GroupFieldComponent: GroupFieldClientComponent = (props) => {
|
export const GroupFieldComponent: GroupFieldClientComponent = (props) => {
|
||||||
const {
|
const {
|
||||||
field: {
|
field,
|
||||||
name,
|
field: { name, admin: { className, description, hideGutter } = {}, fields, label },
|
||||||
admin: { className, description, hideGutter, style, width } = {},
|
|
||||||
fields,
|
|
||||||
label,
|
|
||||||
},
|
|
||||||
path,
|
path,
|
||||||
permissions,
|
permissions,
|
||||||
readOnly,
|
readOnly,
|
||||||
@@ -50,6 +47,8 @@ export const GroupFieldComponent: GroupFieldClientComponent = (props) => {
|
|||||||
|
|
||||||
const isTopLevel = !(isWithinCollapsible || isWithinGroup || isWithinRow)
|
const isTopLevel = !(isWithinCollapsible || isWithinGroup || isWithinRow)
|
||||||
|
|
||||||
|
const styles = useMemo(() => mergeFieldStyles(field), [field])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={[
|
className={[
|
||||||
@@ -67,10 +66,7 @@ export const GroupFieldComponent: GroupFieldClientComponent = (props) => {
|
|||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(' ')}
|
.join(' ')}
|
||||||
id={`field-${path?.replace(/\./g, '__')}`}
|
id={`field-${path?.replace(/\./g, '__')}`}
|
||||||
style={{
|
style={styles}
|
||||||
...style,
|
|
||||||
width,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<GroupProvider>
|
<GroupProvider>
|
||||||
<div className={`${baseClass}__wrap`}>
|
<div className={`${baseClass}__wrap`}>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import type { JSONFieldClientComponent } from 'payload'
|
import type { JSONFieldClientComponent } from 'payload'
|
||||||
|
|
||||||
import React, { useCallback, useEffect, useState } from 'react'
|
import React, { useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
|
|
||||||
import { CodeEditor } from '../../elements/CodeEditor/index.js'
|
import { CodeEditor } from '../../elements/CodeEditor/index.js'
|
||||||
import { RenderCustomComponent } from '../../elements/RenderCustomComponent/index.js'
|
import { RenderCustomComponent } from '../../elements/RenderCustomComponent/index.js'
|
||||||
@@ -10,16 +10,17 @@ import { withCondition } from '../../forms/withCondition/index.js'
|
|||||||
import { FieldDescription } from '../FieldDescription/index.js'
|
import { FieldDescription } from '../FieldDescription/index.js'
|
||||||
import { FieldError } from '../FieldError/index.js'
|
import { FieldError } from '../FieldError/index.js'
|
||||||
import { FieldLabel } from '../FieldLabel/index.js'
|
import { FieldLabel } from '../FieldLabel/index.js'
|
||||||
import { fieldBaseClass } from '../shared/index.js'
|
import { mergeFieldStyles } from '../mergeFieldStyles.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
import { fieldBaseClass } from '../shared/index.js'
|
||||||
|
|
||||||
const baseClass = 'json-field'
|
const baseClass = 'json-field'
|
||||||
|
|
||||||
const JSONFieldComponent: JSONFieldClientComponent = (props) => {
|
const JSONFieldComponent: JSONFieldClientComponent = (props) => {
|
||||||
const {
|
const {
|
||||||
|
field,
|
||||||
field: {
|
field: {
|
||||||
name,
|
admin: { className, description, editorOptions, maxHeight } = {},
|
||||||
admin: { className, description, editorOptions, maxHeight, style, width } = {},
|
|
||||||
jsonSchema,
|
jsonSchema,
|
||||||
label,
|
label,
|
||||||
localized,
|
localized,
|
||||||
@@ -105,6 +106,8 @@ const JSONFieldComponent: JSONFieldClientComponent = (props) => {
|
|||||||
setHasLoadedValue(true)
|
setHasLoadedValue(true)
|
||||||
}, [initialValue, value, hasLoadedValue])
|
}, [initialValue, value, hasLoadedValue])
|
||||||
|
|
||||||
|
const styles = useMemo(() => mergeFieldStyles(field), [field])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={[
|
className={[
|
||||||
@@ -116,10 +119,7 @@ const JSONFieldComponent: JSONFieldClientComponent = (props) => {
|
|||||||
]
|
]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(' ')}
|
.join(' ')}
|
||||||
style={{
|
style={styles}
|
||||||
...style,
|
|
||||||
width,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<RenderCustomComponent
|
<RenderCustomComponent
|
||||||
CustomComponent={Label}
|
CustomComponent={Label}
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ const JoinFieldComponent: JoinFieldClientComponent = (props) => {
|
|||||||
const {
|
const {
|
||||||
field,
|
field,
|
||||||
field: {
|
field: {
|
||||||
name,
|
|
||||||
admin: { allowCreate },
|
admin: { allowCreate },
|
||||||
collection,
|
collection,
|
||||||
label,
|
label,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type { NumberFieldClientComponent, NumberFieldClientProps } from 'payload
|
|||||||
|
|
||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
import { isNumber } from 'payload/shared'
|
import { isNumber } from 'payload/shared'
|
||||||
import React, { useCallback, useEffect, useState } from 'react'
|
import React, { useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
|
|
||||||
import type { Option } from '../../elements/ReactSelect/types.js'
|
import type { Option } from '../../elements/ReactSelect/types.js'
|
||||||
|
|
||||||
@@ -15,20 +15,19 @@ import { useTranslation } from '../../providers/Translation/index.js'
|
|||||||
import { FieldDescription } from '../FieldDescription/index.js'
|
import { FieldDescription } from '../FieldDescription/index.js'
|
||||||
import { FieldError } from '../FieldError/index.js'
|
import { FieldError } from '../FieldError/index.js'
|
||||||
import { FieldLabel } from '../FieldLabel/index.js'
|
import { FieldLabel } from '../FieldLabel/index.js'
|
||||||
import { fieldBaseClass } from '../shared/index.js'
|
import { mergeFieldStyles } from '../mergeFieldStyles.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
import { fieldBaseClass } from '../shared/index.js'
|
||||||
|
|
||||||
const NumberFieldComponent: NumberFieldClientComponent = (props) => {
|
const NumberFieldComponent: NumberFieldClientComponent = (props) => {
|
||||||
const {
|
const {
|
||||||
|
field,
|
||||||
field: {
|
field: {
|
||||||
name,
|
|
||||||
admin: {
|
admin: {
|
||||||
className,
|
className,
|
||||||
description,
|
description,
|
||||||
placeholder,
|
placeholder,
|
||||||
step = 1,
|
step = 1,
|
||||||
style,
|
|
||||||
width,
|
|
||||||
} = {} as NumberFieldClientProps['field']['admin'],
|
} = {} as NumberFieldClientProps['field']['admin'],
|
||||||
hasMany = false,
|
hasMany = false,
|
||||||
label,
|
label,
|
||||||
@@ -123,6 +122,8 @@ const NumberFieldComponent: NumberFieldClientComponent = (props) => {
|
|||||||
}
|
}
|
||||||
}, [value, hasMany])
|
}, [value, hasMany])
|
||||||
|
|
||||||
|
const styles = useMemo(() => mergeFieldStyles(field), [field])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={[
|
className={[
|
||||||
@@ -135,10 +136,7 @@ const NumberFieldComponent: NumberFieldClientComponent = (props) => {
|
|||||||
]
|
]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(' ')}
|
.join(' ')}
|
||||||
style={{
|
style={styles}
|
||||||
...style,
|
|
||||||
width,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<RenderCustomComponent
|
<RenderCustomComponent
|
||||||
CustomComponent={Label}
|
CustomComponent={Label}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import type { PasswordFieldValidation, PayloadRequest } from 'payload'
|
import type { PasswordFieldValidation, PayloadRequest } from 'payload'
|
||||||
|
|
||||||
import { password } from 'payload/shared'
|
import { password } from 'payload/shared'
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback, useMemo } from 'react'
|
||||||
|
|
||||||
import type { PasswordFieldProps } from './types.js'
|
import type { PasswordFieldProps } from './types.js'
|
||||||
|
|
||||||
@@ -11,22 +11,21 @@ import { withCondition } from '../../forms/withCondition/index.js'
|
|||||||
import { useConfig } from '../../providers/Config/index.js'
|
import { useConfig } from '../../providers/Config/index.js'
|
||||||
import { useLocale } from '../../providers/Locale/index.js'
|
import { useLocale } from '../../providers/Locale/index.js'
|
||||||
import { useTranslation } from '../../providers/Translation/index.js'
|
import { useTranslation } from '../../providers/Translation/index.js'
|
||||||
import { isFieldRTL } from '../shared/index.js'
|
import { mergeFieldStyles } from '../mergeFieldStyles.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
import { isFieldRTL } from '../shared/index.js'
|
||||||
import { PasswordInput } from './input.js'
|
import { PasswordInput } from './input.js'
|
||||||
|
|
||||||
const PasswordFieldComponent: React.FC<PasswordFieldProps> = (props) => {
|
const PasswordFieldComponent: React.FC<PasswordFieldProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
autoComplete,
|
autoComplete,
|
||||||
|
field,
|
||||||
field: {
|
field: {
|
||||||
name,
|
|
||||||
admin: {
|
admin: {
|
||||||
className,
|
className,
|
||||||
disabled: disabledFromProps,
|
disabled: disabledFromProps,
|
||||||
placeholder,
|
placeholder,
|
||||||
rtl,
|
rtl,
|
||||||
style,
|
|
||||||
width,
|
|
||||||
} = {} as PasswordFieldProps['field']['admin'],
|
} = {} as PasswordFieldProps['field']['admin'],
|
||||||
label,
|
label,
|
||||||
localized,
|
localized,
|
||||||
@@ -86,6 +85,8 @@ const PasswordFieldComponent: React.FC<PasswordFieldProps> = (props) => {
|
|||||||
localizationConfig: config.localization || undefined,
|
localizationConfig: config.localization || undefined,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const styles = useMemo(() => mergeFieldStyles(field), [field])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PasswordInput
|
<PasswordInput
|
||||||
AfterInput={AfterInput}
|
AfterInput={AfterInput}
|
||||||
@@ -107,9 +108,8 @@ const PasswordFieldComponent: React.FC<PasswordFieldProps> = (props) => {
|
|||||||
required={required}
|
required={required}
|
||||||
rtl={renderRTL}
|
rtl={renderRTL}
|
||||||
showError={showError}
|
showError={showError}
|
||||||
style={style}
|
style={styles}
|
||||||
value={(value as string) || ''}
|
value={(value as string) || ''}
|
||||||
width={width}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import type { PointFieldClientComponent, PointFieldValidation } from 'payload'
|
import type { PointFieldClientComponent, PointFieldValidation } from 'payload'
|
||||||
|
|
||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback, useMemo } from 'react'
|
||||||
|
|
||||||
import { RenderCustomComponent } from '../../elements/RenderCustomComponent/index.js'
|
import { RenderCustomComponent } from '../../elements/RenderCustomComponent/index.js'
|
||||||
import { FieldDescription } from '../../fields/FieldDescription/index.js'
|
import { FieldDescription } from '../../fields/FieldDescription/index.js'
|
||||||
@@ -11,16 +11,17 @@ import { FieldLabel } from '../../fields/FieldLabel/index.js'
|
|||||||
import { useField } from '../../forms/useField/index.js'
|
import { useField } from '../../forms/useField/index.js'
|
||||||
import { withCondition } from '../../forms/withCondition/index.js'
|
import { withCondition } from '../../forms/withCondition/index.js'
|
||||||
import { useTranslation } from '../../providers/Translation/index.js'
|
import { useTranslation } from '../../providers/Translation/index.js'
|
||||||
import { fieldBaseClass } from '../shared/index.js'
|
import { mergeFieldStyles } from '../mergeFieldStyles.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
import { fieldBaseClass } from '../shared/index.js'
|
||||||
|
|
||||||
const baseClass = 'point'
|
const baseClass = 'point'
|
||||||
|
|
||||||
export const PointFieldComponent: PointFieldClientComponent = (props) => {
|
export const PointFieldComponent: PointFieldClientComponent = (props) => {
|
||||||
const {
|
const {
|
||||||
|
field,
|
||||||
field: {
|
field: {
|
||||||
name,
|
admin: { className, description, placeholder, step } = {},
|
||||||
admin: { className, description, placeholder, step, style, width } = {},
|
|
||||||
label,
|
label,
|
||||||
localized,
|
localized,
|
||||||
required,
|
required,
|
||||||
@@ -71,6 +72,8 @@ export const PointFieldComponent: PointFieldClientComponent = (props) => {
|
|||||||
return `${fieldLabel}${fieldLabel ? ' - ' : ''}${suffix}`
|
return `${fieldLabel}${fieldLabel ? ' - ' : ''}${suffix}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const styles = useMemo(() => mergeFieldStyles(field), [field])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={[
|
className={[
|
||||||
@@ -82,10 +85,7 @@ export const PointFieldComponent: PointFieldClientComponent = (props) => {
|
|||||||
]
|
]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(' ')}
|
.join(' ')}
|
||||||
style={{
|
style={styles}
|
||||||
...style,
|
|
||||||
width,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<ul className={`${baseClass}__wrap`}>
|
<ul className={`${baseClass}__wrap`}>
|
||||||
<li>
|
<li>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import type { RadioFieldClientComponent, RadioFieldClientProps } from 'payload'
|
import type { RadioFieldClientComponent, RadioFieldClientProps } from 'payload'
|
||||||
|
|
||||||
import { optionIsObject } from 'payload/shared'
|
import { optionIsObject } from 'payload/shared'
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback, useMemo } from 'react'
|
||||||
|
|
||||||
import { RenderCustomComponent } from '../../elements/RenderCustomComponent/index.js'
|
import { RenderCustomComponent } from '../../elements/RenderCustomComponent/index.js'
|
||||||
import { FieldDescription } from '../../fields/FieldDescription/index.js'
|
import { FieldDescription } from '../../fields/FieldDescription/index.js'
|
||||||
@@ -11,8 +11,9 @@ import { FieldLabel } from '../../fields/FieldLabel/index.js'
|
|||||||
import { useForm } from '../../forms/Form/context.js'
|
import { useForm } from '../../forms/Form/context.js'
|
||||||
import { useField } from '../../forms/useField/index.js'
|
import { useField } from '../../forms/useField/index.js'
|
||||||
import { withCondition } from '../../forms/withCondition/index.js'
|
import { withCondition } from '../../forms/withCondition/index.js'
|
||||||
import { fieldBaseClass } from '../shared/index.js'
|
import { mergeFieldStyles } from '../mergeFieldStyles.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
import { fieldBaseClass } from '../shared/index.js'
|
||||||
import { Radio } from './Radio/index.js'
|
import { Radio } from './Radio/index.js'
|
||||||
|
|
||||||
const baseClass = 'radio-group'
|
const baseClass = 'radio-group'
|
||||||
@@ -20,13 +21,12 @@ const baseClass = 'radio-group'
|
|||||||
const RadioGroupFieldComponent: RadioFieldClientComponent = (props) => {
|
const RadioGroupFieldComponent: RadioFieldClientComponent = (props) => {
|
||||||
const {
|
const {
|
||||||
disableModifyingForm: disableModifyingFormFromProps,
|
disableModifyingForm: disableModifyingFormFromProps,
|
||||||
|
field,
|
||||||
field: {
|
field: {
|
||||||
admin: {
|
admin: {
|
||||||
className,
|
className,
|
||||||
description,
|
description,
|
||||||
layout = 'horizontal',
|
layout = 'horizontal',
|
||||||
style,
|
|
||||||
width,
|
|
||||||
} = {} as RadioFieldClientProps['field']['admin'],
|
} = {} as RadioFieldClientProps['field']['admin'],
|
||||||
label,
|
label,
|
||||||
localized,
|
localized,
|
||||||
@@ -63,6 +63,8 @@ const RadioGroupFieldComponent: RadioFieldClientComponent = (props) => {
|
|||||||
|
|
||||||
const value = valueFromContext || valueFromProps
|
const value = valueFromContext || valueFromProps
|
||||||
|
|
||||||
|
const styles = useMemo(() => mergeFieldStyles(field), [field])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={[
|
className={[
|
||||||
@@ -75,10 +77,7 @@ const RadioGroupFieldComponent: RadioFieldClientComponent = (props) => {
|
|||||||
]
|
]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(' ')}
|
.join(' ')}
|
||||||
style={{
|
style={styles}
|
||||||
...style,
|
|
||||||
width,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<RenderCustomComponent
|
<RenderCustomComponent
|
||||||
CustomComponent={Error}
|
CustomComponent={Error}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type { PaginatedDocs, RelationshipFieldClientComponent, Where } from 'pay
|
|||||||
|
|
||||||
import { wordBoundariesRegex } from 'payload/shared'
|
import { wordBoundariesRegex } from 'payload/shared'
|
||||||
import * as qs from 'qs-esm'
|
import * as qs from 'qs-esm'
|
||||||
import React, { useCallback, useEffect, useReducer, useRef, useState } from 'react'
|
import React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react'
|
||||||
|
|
||||||
import type { DocumentDrawerProps } from '../../elements/DocumentDrawer/types.js'
|
import type { DocumentDrawerProps } from '../../elements/DocumentDrawer/types.js'
|
||||||
import type { ReactSelectAdapterProps } from '../../elements/ReactSelect/types.js'
|
import type { ReactSelectAdapterProps } from '../../elements/ReactSelect/types.js'
|
||||||
@@ -24,10 +24,11 @@ import { useAuth } from '../../providers/Auth/index.js'
|
|||||||
import { useConfig } from '../../providers/Config/index.js'
|
import { useConfig } from '../../providers/Config/index.js'
|
||||||
import { useLocale } from '../../providers/Locale/index.js'
|
import { useLocale } from '../../providers/Locale/index.js'
|
||||||
import { useTranslation } from '../../providers/Translation/index.js'
|
import { useTranslation } from '../../providers/Translation/index.js'
|
||||||
|
import { mergeFieldStyles } from '../mergeFieldStyles.js'
|
||||||
import { fieldBaseClass } from '../shared/index.js'
|
import { fieldBaseClass } from '../shared/index.js'
|
||||||
import { createRelationMap } from './createRelationMap.js'
|
import { createRelationMap } from './createRelationMap.js'
|
||||||
import { findOptionsByValue } from './findOptionsByValue.js'
|
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
import { findOptionsByValue } from './findOptionsByValue.js'
|
||||||
import { optionsReducer } from './optionsReducer.js'
|
import { optionsReducer } from './optionsReducer.js'
|
||||||
import { MultiValueLabel } from './select-components/MultiValueLabel/index.js'
|
import { MultiValueLabel } from './select-components/MultiValueLabel/index.js'
|
||||||
import { SingleValue } from './select-components/SingleValue/index.js'
|
import { SingleValue } from './select-components/SingleValue/index.js'
|
||||||
@@ -38,8 +39,8 @@ const baseClass = 'relationship'
|
|||||||
|
|
||||||
const RelationshipFieldComponent: RelationshipFieldClientComponent = (props) => {
|
const RelationshipFieldComponent: RelationshipFieldClientComponent = (props) => {
|
||||||
const {
|
const {
|
||||||
|
field,
|
||||||
field: {
|
field: {
|
||||||
name,
|
|
||||||
admin: {
|
admin: {
|
||||||
allowCreate = true,
|
allowCreate = true,
|
||||||
allowEdit = true,
|
allowEdit = true,
|
||||||
@@ -47,8 +48,6 @@ const RelationshipFieldComponent: RelationshipFieldClientComponent = (props) =>
|
|||||||
description,
|
description,
|
||||||
isSortable = true,
|
isSortable = true,
|
||||||
sortOptions,
|
sortOptions,
|
||||||
style,
|
|
||||||
width,
|
|
||||||
} = {},
|
} = {},
|
||||||
hasMany,
|
hasMany,
|
||||||
label,
|
label,
|
||||||
@@ -575,6 +574,8 @@ const RelationshipFieldComponent: RelationshipFieldClientComponent = (props) =>
|
|||||||
valueToRender.value = null
|
valueToRender.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const styles = useMemo(() => mergeFieldStyles(field), [field])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={[
|
className={[
|
||||||
@@ -589,10 +590,7 @@ const RelationshipFieldComponent: RelationshipFieldClientComponent = (props) =>
|
|||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(' ')}
|
.join(' ')}
|
||||||
id={`field-${path.replace(/\./g, '__')}`}
|
id={`field-${path.replace(/\./g, '__')}`}
|
||||||
style={{
|
style={styles}
|
||||||
...style,
|
|
||||||
width,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<RenderCustomComponent
|
<RenderCustomComponent
|
||||||
CustomComponent={Label}
|
CustomComponent={Label}
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ export type SelectInputProps = {
|
|||||||
readonly showError?: boolean
|
readonly showError?: boolean
|
||||||
readonly style?: React.CSSProperties
|
readonly style?: React.CSSProperties
|
||||||
readonly value?: string | string[]
|
readonly value?: string | string[]
|
||||||
readonly width?: React.CSSProperties['width']
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SelectInput: React.FC<SelectInputProps> = (props) => {
|
export const SelectInput: React.FC<SelectInputProps> = (props) => {
|
||||||
@@ -60,7 +59,6 @@ export const SelectInput: React.FC<SelectInputProps> = (props) => {
|
|||||||
showError,
|
showError,
|
||||||
style,
|
style,
|
||||||
value,
|
value,
|
||||||
width,
|
|
||||||
} = props
|
} = props
|
||||||
|
|
||||||
const { i18n } = useTranslation()
|
const { i18n } = useTranslation()
|
||||||
@@ -95,10 +93,7 @@ export const SelectInput: React.FC<SelectInputProps> = (props) => {
|
|||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(' ')}
|
.join(' ')}
|
||||||
id={`field-${path.replace(/\./g, '__')}`}
|
id={`field-${path.replace(/\./g, '__')}`}
|
||||||
style={{
|
style={style}
|
||||||
...style,
|
|
||||||
width,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<RenderCustomComponent
|
<RenderCustomComponent
|
||||||
CustomComponent={Label}
|
CustomComponent={Label}
|
||||||
|
|||||||
@@ -6,13 +6,14 @@ import type {
|
|||||||
SelectFieldClientProps,
|
SelectFieldClientProps,
|
||||||
} from 'payload'
|
} from 'payload'
|
||||||
|
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback, useMemo } from 'react'
|
||||||
|
|
||||||
import type { ReactSelectAdapterProps } from '../../elements/ReactSelect/types.js'
|
import type { ReactSelectAdapterProps } from '../../elements/ReactSelect/types.js'
|
||||||
import type { SelectInputProps } from './Input.js'
|
import type { SelectInputProps } from './Input.js'
|
||||||
|
|
||||||
import { useField } from '../../forms/useField/index.js'
|
import { useField } from '../../forms/useField/index.js'
|
||||||
import { withCondition } from '../../forms/withCondition/index.js'
|
import { withCondition } from '../../forms/withCondition/index.js'
|
||||||
|
import { mergeFieldStyles } from '../mergeFieldStyles.js'
|
||||||
import { SelectInput } from './Input.js'
|
import { SelectInput } from './Input.js'
|
||||||
|
|
||||||
const formatOptions = (options: Option[]): OptionObject[] =>
|
const formatOptions = (options: Option[]): OptionObject[] =>
|
||||||
@@ -29,6 +30,7 @@ const formatOptions = (options: Option[]): OptionObject[] =>
|
|||||||
|
|
||||||
const SelectFieldComponent: SelectFieldClientComponent = (props) => {
|
const SelectFieldComponent: SelectFieldClientComponent = (props) => {
|
||||||
const {
|
const {
|
||||||
|
field,
|
||||||
field: {
|
field: {
|
||||||
name,
|
name,
|
||||||
admin: {
|
admin: {
|
||||||
@@ -36,8 +38,6 @@ const SelectFieldComponent: SelectFieldClientComponent = (props) => {
|
|||||||
description,
|
description,
|
||||||
isClearable = true,
|
isClearable = true,
|
||||||
isSortable = true,
|
isSortable = true,
|
||||||
style,
|
|
||||||
width,
|
|
||||||
} = {} as SelectFieldClientProps['field']['admin'],
|
} = {} as SelectFieldClientProps['field']['admin'],
|
||||||
hasMany = false,
|
hasMany = false,
|
||||||
label,
|
label,
|
||||||
@@ -96,6 +96,8 @@ const SelectFieldComponent: SelectFieldClientComponent = (props) => {
|
|||||||
[readOnly, hasMany, setValue, onChangeFromProps],
|
[readOnly, hasMany, setValue, onChangeFromProps],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const styles = useMemo(() => mergeFieldStyles(field), [field])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SelectInput
|
<SelectInput
|
||||||
AfterInput={AfterInput}
|
AfterInput={AfterInput}
|
||||||
@@ -116,9 +118,8 @@ const SelectFieldComponent: SelectFieldClientComponent = (props) => {
|
|||||||
path={path}
|
path={path}
|
||||||
readOnly={readOnly}
|
readOnly={readOnly}
|
||||||
showError={showError}
|
showError={showError}
|
||||||
style={style}
|
style={styles}
|
||||||
value={value as string | string[]}
|
value={value as string | string[]}
|
||||||
width={width}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ export const TextInput: React.FC<TextInputProps> = (props) => {
|
|||||||
style,
|
style,
|
||||||
value,
|
value,
|
||||||
valueToRender,
|
valueToRender,
|
||||||
width,
|
|
||||||
} = props
|
} = props
|
||||||
|
|
||||||
const { i18n, t } = useTranslation()
|
const { i18n, t } = useTranslation()
|
||||||
@@ -57,10 +56,7 @@ export const TextInput: React.FC<TextInputProps> = (props) => {
|
|||||||
]
|
]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(' ')}
|
.join(' ')}
|
||||||
style={{
|
style={style}
|
||||||
...style,
|
|
||||||
width,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<RenderCustomComponent
|
<RenderCustomComponent
|
||||||
CustomComponent={Label}
|
CustomComponent={Label}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import type { TextFieldClientComponent } from 'payload'
|
import type { TextFieldClientComponent } from 'payload'
|
||||||
|
|
||||||
import React, { useCallback, useEffect, useState } from 'react'
|
import React, { useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
|
|
||||||
import type { Option } from '../../elements/ReactSelect/types.js'
|
import type { Option } from '../../elements/ReactSelect/types.js'
|
||||||
import type { TextInputProps } from './types.js'
|
import type { TextInputProps } from './types.js'
|
||||||
@@ -10,17 +10,18 @@ import { useField } from '../../forms/useField/index.js'
|
|||||||
import { withCondition } from '../../forms/withCondition/index.js'
|
import { withCondition } from '../../forms/withCondition/index.js'
|
||||||
import { useConfig } from '../../providers/Config/index.js'
|
import { useConfig } from '../../providers/Config/index.js'
|
||||||
import { useLocale } from '../../providers/Locale/index.js'
|
import { useLocale } from '../../providers/Locale/index.js'
|
||||||
|
import { mergeFieldStyles } from '../mergeFieldStyles.js'
|
||||||
import { isFieldRTL } from '../shared/index.js'
|
import { isFieldRTL } from '../shared/index.js'
|
||||||
import { TextInput } from './Input.js'
|
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
import { TextInput } from './Input.js'
|
||||||
|
|
||||||
export { TextInput, TextInputProps }
|
export { TextInput, TextInputProps }
|
||||||
|
|
||||||
const TextFieldComponent: TextFieldClientComponent = (props) => {
|
const TextFieldComponent: TextFieldClientComponent = (props) => {
|
||||||
const {
|
const {
|
||||||
|
field,
|
||||||
field: {
|
field: {
|
||||||
name,
|
admin: { className, description, placeholder, rtl } = {},
|
||||||
admin: { className, description, placeholder, rtl, style, width } = {},
|
|
||||||
hasMany,
|
hasMany,
|
||||||
label,
|
label,
|
||||||
localized,
|
localized,
|
||||||
@@ -109,6 +110,8 @@ const TextFieldComponent: TextFieldClientComponent = (props) => {
|
|||||||
}
|
}
|
||||||
}, [value, hasMany])
|
}, [value, hasMany])
|
||||||
|
|
||||||
|
const styles = useMemo(() => mergeFieldStyles(field), [field])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TextInput
|
<TextInput
|
||||||
AfterInput={AfterInput}
|
AfterInput={AfterInput}
|
||||||
@@ -137,10 +140,9 @@ const TextFieldComponent: TextFieldClientComponent = (props) => {
|
|||||||
required={required}
|
required={required}
|
||||||
rtl={renderRTL}
|
rtl={renderRTL}
|
||||||
showError={showError}
|
showError={showError}
|
||||||
style={style}
|
style={styles}
|
||||||
value={(value as string) || ''}
|
value={(value as string) || ''}
|
||||||
valueToRender={valueToRender as Option[]}
|
valueToRender={valueToRender as Option[]}
|
||||||
width={width}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,5 +37,4 @@ export type TextInputProps = {
|
|||||||
readonly style?: React.CSSProperties
|
readonly style?: React.CSSProperties
|
||||||
readonly value?: string
|
readonly value?: string
|
||||||
readonly valueToRender?: Option[]
|
readonly valueToRender?: Option[]
|
||||||
readonly width?: React.CSSProperties['width']
|
|
||||||
} & SharedTextFieldProps
|
} & SharedTextFieldProps
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ export const TextareaInput: React.FC<TextAreaInputProps> = (props) => {
|
|||||||
showError,
|
showError,
|
||||||
style,
|
style,
|
||||||
value,
|
value,
|
||||||
width,
|
|
||||||
} = props
|
} = props
|
||||||
|
|
||||||
const { i18n } = useTranslation()
|
const { i18n } = useTranslation()
|
||||||
@@ -49,10 +48,7 @@ export const TextareaInput: React.FC<TextAreaInputProps> = (props) => {
|
|||||||
]
|
]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(' ')}
|
.join(' ')}
|
||||||
style={{
|
style={style}
|
||||||
...style,
|
|
||||||
width,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<RenderCustomComponent
|
<RenderCustomComponent
|
||||||
CustomComponent={Label}
|
CustomComponent={Label}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import type { TextareaFieldClientComponent, TextareaFieldValidation } from 'payload'
|
import type { TextareaFieldClientComponent, TextareaFieldValidation } from 'payload'
|
||||||
|
|
||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback, useMemo } from 'react'
|
||||||
|
|
||||||
import type { TextAreaInputProps } from './types.js'
|
import type { TextAreaInputProps } from './types.js'
|
||||||
|
|
||||||
@@ -11,17 +11,18 @@ import { withCondition } from '../../forms/withCondition/index.js'
|
|||||||
import { useConfig } from '../../providers/Config/index.js'
|
import { useConfig } from '../../providers/Config/index.js'
|
||||||
import { useLocale } from '../../providers/Locale/index.js'
|
import { useLocale } from '../../providers/Locale/index.js'
|
||||||
import { useTranslation } from '../../providers/Translation/index.js'
|
import { useTranslation } from '../../providers/Translation/index.js'
|
||||||
import { isFieldRTL } from '../shared/index.js'
|
import { mergeFieldStyles } from '../mergeFieldStyles.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
import { isFieldRTL } from '../shared/index.js'
|
||||||
import { TextareaInput } from './Input.js'
|
import { TextareaInput } from './Input.js'
|
||||||
|
|
||||||
export { TextareaInput, TextAreaInputProps }
|
export { TextareaInput, TextAreaInputProps }
|
||||||
|
|
||||||
const TextareaFieldComponent: TextareaFieldClientComponent = (props) => {
|
const TextareaFieldComponent: TextareaFieldClientComponent = (props) => {
|
||||||
const {
|
const {
|
||||||
|
field,
|
||||||
field: {
|
field: {
|
||||||
name,
|
admin: { className, description, placeholder, rows, rtl } = {},
|
||||||
admin: { className, description, placeholder, rows, rtl, style, width } = {},
|
|
||||||
label,
|
label,
|
||||||
localized,
|
localized,
|
||||||
maxLength,
|
maxLength,
|
||||||
@@ -67,6 +68,8 @@ const TextareaFieldComponent: TextareaFieldClientComponent = (props) => {
|
|||||||
validate: memoizedValidate,
|
validate: memoizedValidate,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const styles = useMemo(() => mergeFieldStyles(field), [field])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TextareaInput
|
<TextareaInput
|
||||||
AfterInput={AfterInput}
|
AfterInput={AfterInput}
|
||||||
@@ -88,9 +91,8 @@ const TextareaFieldComponent: TextareaFieldClientComponent = (props) => {
|
|||||||
rows={rows}
|
rows={rows}
|
||||||
rtl={isRTL}
|
rtl={isRTL}
|
||||||
showError={showError}
|
showError={showError}
|
||||||
style={style}
|
style={styles}
|
||||||
value={value}
|
value={value}
|
||||||
width={width}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,5 +26,4 @@ export type TextAreaInputProps = {
|
|||||||
readonly style?: React.CSSProperties
|
readonly style?: React.CSSProperties
|
||||||
readonly value?: string
|
readonly value?: string
|
||||||
readonly valueToRender?: string
|
readonly valueToRender?: string
|
||||||
readonly width?: React.CSSProperties['width']
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ export type UploadInputProps = {
|
|||||||
readonly showError?: boolean
|
readonly showError?: boolean
|
||||||
readonly style?: React.CSSProperties
|
readonly style?: React.CSSProperties
|
||||||
readonly value?: (number | string)[] | (number | string)
|
readonly value?: (number | string)[] | (number | string)
|
||||||
readonly width?: React.CSSProperties['width']
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function UploadInput(props: UploadInputProps) {
|
export function UploadInput(props: UploadInputProps) {
|
||||||
@@ -102,7 +101,6 @@ export function UploadInput(props: UploadInputProps) {
|
|||||||
showError,
|
showError,
|
||||||
style,
|
style,
|
||||||
value,
|
value,
|
||||||
width,
|
|
||||||
} = props
|
} = props
|
||||||
|
|
||||||
const [populatedDocs, setPopulatedDocs] = React.useState<
|
const [populatedDocs, setPopulatedDocs] = React.useState<
|
||||||
@@ -169,7 +167,7 @@ export function UploadInput(props: UploadInputProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}, [activeRelationTo, permissions, readOnly, allowCreate])
|
}, [activeRelationTo, permissions, allowCreate])
|
||||||
|
|
||||||
const onChange = React.useCallback(
|
const onChange = React.useCallback(
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
@@ -447,10 +445,7 @@ export function UploadInput(props: UploadInputProps) {
|
|||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(' ')}
|
.join(' ')}
|
||||||
id={`field-${path?.replace(/\./g, '__')}`}
|
id={`field-${path?.replace(/\./g, '__')}`}
|
||||||
style={{
|
style={style}
|
||||||
...style,
|
|
||||||
width,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<RenderCustomComponent
|
<RenderCustomComponent
|
||||||
CustomComponent={Label}
|
CustomComponent={Label}
|
||||||
|
|||||||
@@ -2,12 +2,13 @@
|
|||||||
|
|
||||||
import type { UploadFieldClientProps } from 'payload'
|
import type { UploadFieldClientProps } from 'payload'
|
||||||
|
|
||||||
import React from 'react'
|
import React, { useMemo } from 'react'
|
||||||
|
|
||||||
import { useField } from '../../forms/useField/index.js'
|
import { useField } from '../../forms/useField/index.js'
|
||||||
import { withCondition } from '../../forms/withCondition/index.js'
|
import { withCondition } from '../../forms/withCondition/index.js'
|
||||||
import { useConfig } from '../../providers/Config/index.js'
|
import { useConfig } from '../../providers/Config/index.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
import { mergeFieldStyles } from '../mergeFieldStyles.js'
|
||||||
import { UploadInput } from './Input.js'
|
import { UploadInput } from './Input.js'
|
||||||
|
|
||||||
export { UploadInput } from './Input.js'
|
export { UploadInput } from './Input.js'
|
||||||
@@ -17,9 +18,9 @@ export const baseClass = 'upload'
|
|||||||
|
|
||||||
export function UploadComponent(props: UploadFieldClientProps) {
|
export function UploadComponent(props: UploadFieldClientProps) {
|
||||||
const {
|
const {
|
||||||
|
field,
|
||||||
field: {
|
field: {
|
||||||
name,
|
admin: { allowCreate, className, description, isSortable } = {},
|
||||||
admin: { allowCreate, className, description, isSortable, style, width } = {},
|
|
||||||
hasMany,
|
hasMany,
|
||||||
label,
|
label,
|
||||||
localized,
|
localized,
|
||||||
@@ -54,6 +55,8 @@ export function UploadComponent(props: UploadFieldClientProps) {
|
|||||||
validate: memoizedValidate,
|
validate: memoizedValidate,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const styles = useMemo(() => mergeFieldStyles(field), [field])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UploadInput
|
<UploadInput
|
||||||
AfterInput={AfterInput}
|
AfterInput={AfterInput}
|
||||||
@@ -78,9 +81,8 @@ export function UploadComponent(props: UploadFieldClientProps) {
|
|||||||
required={required}
|
required={required}
|
||||||
serverURL={config.serverURL}
|
serverURL={config.serverURL}
|
||||||
showError={showError}
|
showError={showError}
|
||||||
style={style}
|
style={styles}
|
||||||
value={value}
|
value={value}
|
||||||
width={width}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
20
packages/ui/src/fields/mergeFieldStyles.ts
Normal file
20
packages/ui/src/fields/mergeFieldStyles.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import type { ClientField } from 'payload'
|
||||||
|
|
||||||
|
export const mergeFieldStyles = (
|
||||||
|
field: ClientField | Omit<ClientField, 'type'>,
|
||||||
|
): React.CSSProperties => ({
|
||||||
|
...(field?.admin?.style || {}),
|
||||||
|
...(field?.admin?.width
|
||||||
|
? {
|
||||||
|
'--field-width': field.admin.width,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
flex: '1 1 auto',
|
||||||
|
}),
|
||||||
|
// allow flex overrides to still take precedence over the fallback
|
||||||
|
...(field?.admin?.style?.flex
|
||||||
|
? {
|
||||||
|
flex: field.admin.style.flex,
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user