fix: object validation collapsed (#416)

This commit is contained in:
Daniel Lautzenheiser 2023-01-23 14:36:52 -05:00 committed by GitHub
parent dad93b42fc
commit d17378d557
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 4 deletions

View File

@ -606,6 +606,27 @@ collections:
name: thumb
widget: image
required: false
- label: Collapsed, optional with required children
name: collapsed_optional_with_required_children
widget: object
required: false
collapsed: true
fields:
- name: layout
widget: hidden
default: post
- label: Number of posts on frontpage
name: front_limit
widget: number
required: true
- label: Author
name: author
widget: string
required: true
- label: Thumbnail
name: thumb
widget: image
required: true
- name: relation
label: Relation
file: _widgets/relation.json

View File

@ -3,9 +3,13 @@ import { getDataPath } from '@staticcms/core/lib/i18n';
import type { I18nSettings } from '@staticcms/core/interface';
import type { RootState } from '@staticcms/core/store';
export const getEntryDataPath = (i18n: I18nSettings | undefined) => {
return (i18n && getDataPath(i18n.currentLocale, i18n.defaultLocale)) || ['data'];
};
export const selectFieldErrors =
(path: string, i18n: I18nSettings | undefined) => (state: RootState) => {
const dataPath = (i18n && getDataPath(i18n.currentLocale, i18n.defaultLocale)) || ['data'];
const dataPath = getEntryDataPath(i18n);
const fullPath = `${dataPath.join('.')}.${path}`;
return state.entryDraft.fieldsErrors[fullPath] ?? [];
};

View File

@ -6,6 +6,7 @@ import ObjectWidgetTopBar from '@staticcms/core/components/UI/ObjectWidgetTopBar
import Outline from '@staticcms/core/components/UI/Outline';
import { transientOptions } from '@staticcms/core/lib';
import { compileStringTemplate } from '@staticcms/core/lib/widgets/stringTemplate';
import { getEntryDataPath } from '@staticcms/core/reducers/selectors/entryDraft';
import type { ObjectField, ObjectValue, WidgetControlProps } from '@staticcms/core/interface';
import type { FC } from 'react';
@ -61,7 +62,7 @@ const ObjectControl: FC<WidgetControlProps<ObjectValue, ObjectField>> = ({
hasErrors,
value = {},
}) => {
const [collapsed, setCollapsed] = useState(false);
const [collapsed, setCollapsed] = useState(field.collapsed ?? false);
const handleCollapseToggle = useCallback(() => {
setCollapsed(!collapsed);
@ -75,6 +76,13 @@ const ObjectControl: FC<WidgetControlProps<ObjectValue, ObjectField>> = ({
const multiFields = useMemo(() => field.fields, [field.fields]);
const childHasError = useMemo(() => {
const dataPath = getEntryDataPath(i18n);
const fullPath = `${dataPath}.${path}`;
return Boolean(Object.keys(fieldsErrors).find(key => key.startsWith(fullPath)));
}, [fieldsErrors, i18n, path]);
const renderedField = useMemo(() => {
return (
multiFields?.map((field, index) => {
@ -132,7 +140,7 @@ const ObjectControl: FC<WidgetControlProps<ObjectValue, ObjectField>> = ({
collapsed={collapsed}
onCollapseToggle={handleCollapseToggle}
heading={objectLabel}
hasError={hasErrors}
hasError={hasErrors || childHasError}
t={t}
testId="object-title"
/>
@ -140,7 +148,9 @@ const ObjectControl: FC<WidgetControlProps<ObjectValue, ObjectField>> = ({
<StyledFieldsBox $collapsed={collapsed} key="object-control-fields">
{renderedField}
</StyledFieldsBox>
{forList ? null : <Outline key="object-control-outline" hasError={hasErrors} />}
{forList ? null : (
<Outline key="object-control-outline" hasError={hasErrors || childHasError} />
)}
</StyledObjectControlWrapper>
);
}