diff --git a/dev/test-studio/preview/FieldGroups.tsx b/dev/test-studio/preview/FieldGroups.tsx
new file mode 100644
index 000000000000..1a2a73ee8355
--- /dev/null
+++ b/dev/test-studio/preview/FieldGroups.tsx
@@ -0,0 +1,50 @@
+import {Box, Card, Stack, Text} from '@sanity/ui'
+
+import {useQuery} from './loader'
+
+export function FieldGroups(): JSX.Element {
+ const {data, loading, error} = useQuery<
+ {
+ _id: string
+ field1: string | null
+ field2: string | null
+ nested: {
+ field3: string | null
+ field4: string | null
+ field5: string | null
+ } | null
+ }[]
+ >(
+ /* groq */ `*[_type == "fieldGroupsWithFieldsetsHidden"]{_id,field1,field2,nested{field3,field4,field5}}`,
+ )
+
+ if (error) {
+ throw error
+ }
+
+ if (loading) {
+ return
Loading...
+ }
+
+ return (
+
+ {data?.map((item) => {
+ return (
+
+
+ {item.field1 || 'Not Set'}
+ {item.field2 || 'Not Set'}
+ {item.nested && (
+
+ {item.nested.field3 || 'Not Set'}
+ {item.nested.field4 || 'Not Set'}
+ {item.nested.field5 || 'Not Set'}
+
+ )}
+
+
+ )
+ })}
+
+ )
+}
diff --git a/dev/test-studio/preview/main.tsx b/dev/test-studio/preview/main.tsx
index 2d8b6eac32ef..7fb32fa58a77 100644
--- a/dev/test-studio/preview/main.tsx
+++ b/dev/test-studio/preview/main.tsx
@@ -1,14 +1,51 @@
+import {Box, Flex, studioTheme, Tab, TabList, TabPanel, ThemeProvider} from '@sanity/ui'
import {enableVisualEditing} from '@sanity/visual-editing'
-import {Suspense, useEffect} from 'react'
+import {Suspense, useEffect, useState} from 'react'
import {createRoot} from 'react-dom/client'
+import {FieldGroups} from './FieldGroups'
import {useLiveMode} from './loader'
import {SimpleBlockPortableText} from './SimpleBlockPortableText'
function Main() {
+ const [id, setId] = useState('simple')
return (
<>
-
+
+
+
+
+ setId('simple')}
+ selected={id === 'simple'}
+ />
+ setId('nested')}
+ selected={id === 'nested'}
+ />
+
+
+
+ {id === 'simple' && (
+
+
+
+ )}
+
+ {id === 'nested' && (
+
+
+
+ )}
+
+
+
diff --git a/dev/test-studio/schema/debug/fieldGroupsWithFieldsetsHidden.js b/dev/test-studio/schema/debug/fieldGroupsWithFieldsetsHidden.js
new file mode 100644
index 000000000000..2e63fd511f49
--- /dev/null
+++ b/dev/test-studio/schema/debug/fieldGroupsWithFieldsetsHidden.js
@@ -0,0 +1,59 @@
+const group = {
+ name: 'group',
+ title: 'Group',
+ default: true,
+}
+const group2 = {
+ name: 'group2',
+ title: 'Group 2',
+}
+const fieldset = {
+ name: 'fieldset',
+ title: 'Fieldset',
+ options: {collapsed: true},
+}
+
+export default {
+ name: 'fieldGroupsWithFieldsetsHidden',
+ title: 'With default groups and collapsed fieldsets',
+ type: 'document',
+ groups: [group, group2],
+ fieldsets: [fieldset],
+ fields: [
+ {
+ name: 'field1',
+ type: 'string',
+ },
+ {
+ name: 'field2',
+ type: 'string',
+ group: group.name,
+ fieldset: fieldset.name,
+ },
+ {
+ name: 'nested',
+ type: 'object',
+ group: group.name,
+ fieldset: fieldset.name,
+ groups: [group, group2],
+ fieldsets: [fieldset],
+ fields: [
+ {
+ name: 'field3',
+ type: 'string',
+ fieldset: fieldset.name,
+ },
+ {
+ name: 'field4',
+ type: 'string',
+ group: group.name,
+ },
+ {
+ name: 'field5',
+ type: 'string',
+ group: group2.name,
+ },
+ ],
+ },
+ ],
+}
diff --git a/dev/test-studio/schema/index.ts b/dev/test-studio/schema/index.ts
index 51b229532b6b..b579539513f1 100644
--- a/dev/test-studio/schema/index.ts
+++ b/dev/test-studio/schema/index.ts
@@ -32,6 +32,7 @@ import fieldGroupsDefault from './debug/fieldGroupsDefault'
import fieldGroupsMany from './debug/fieldGroupsMany'
import fieldGroupsWithFieldsets from './debug/fieldGroupsWithFieldsets'
import fieldGroupsWithFieldsetsAndValidation from './debug/fieldGroupsWithFieldsetsAndValidation'
+import fieldGroupsWithFieldsetsHidden from './debug/fieldGroupsWithFieldsetsHidden'
import fieldGroupsWithI18n from './debug/fieldGroupsWithI18n'
import fieldGroupsWithValidation from './debug/fieldGroupsWithValidation'
import fieldsets from './debug/fieldsets'
@@ -252,6 +253,7 @@ export const schemaTypes = [
fieldGroupsWithI18n,
fieldGroupsWithValidation,
fieldGroupsWithFieldsetsAndValidation,
+ fieldGroupsWithFieldsetsHidden,
virtualizationInObject,
virtualizationDebug,
diff --git a/dev/test-studio/structure/constants.ts b/dev/test-studio/structure/constants.ts
index fbbc480ed0d0..ffcdea6447a4 100644
--- a/dev/test-studio/structure/constants.ts
+++ b/dev/test-studio/structure/constants.ts
@@ -98,6 +98,7 @@ export const DEBUG_FIELD_GROUP_TYPES = [
'fieldGroupsWithValidation',
'fieldGroupsWithFieldsets',
'fieldGroupsWithFieldsetsAndValidation',
+ 'fieldGroupsWithFieldsetsHidden',
]
export const EXTERNAL_PLUGIN_INPUT_TYPES = ['markdownTest', 'muxVideoPost']
diff --git a/packages/sanity/src/core/form/store/useFormState.ts b/packages/sanity/src/core/form/store/useFormState.ts
index 9d997e0cd245..71c967a9f754 100644
--- a/packages/sanity/src/core/form/store/useFormState.ts
+++ b/packages/sanity/src/core/form/store/useFormState.ts
@@ -7,7 +7,7 @@ import {useLayoutEffect, useMemo, useRef} from 'react'
import {type FormNodePresence} from '../../presence'
import {useCurrentUser} from '../../store'
import {type FIXME_SanityDocument, prepareFormState} from './formState'
-import {type ObjectFormNode, type StateTree} from './types'
+import {type ObjectFormNode, type ObjectMember, type StateTree} from './types'
import {type DocumentFormNode} from './types/nodes'
import {immutableReconcile} from './utils/immutableReconcile'
@@ -77,7 +77,7 @@ export function useFormState<
presence,
validation,
changesOpen,
- }) as ObjectFormNode // TODO: remove type cast
+ }) as ObjectFormNode & {_allMembers: ObjectMember[]} // TODO: remove type cast
const reconciled = immutableReconcile(prev.current, next)
prev.current = reconciled
diff --git a/packages/sanity/src/core/form/store/utils/getExpandOperations.ts b/packages/sanity/src/core/form/store/utils/getExpandOperations.ts
index be285de9c1c3..79acae7bc30d 100644
--- a/packages/sanity/src/core/form/store/utils/getExpandOperations.ts
+++ b/packages/sanity/src/core/form/store/utils/getExpandOperations.ts
@@ -107,19 +107,21 @@ function getObjectFieldsetAndFieldGroupOperations(
// Group handling
const schemaField = node.schemaType.fields.find((field) => field.name === fieldName)
const selectedGroupName = node.groups.find((group) => group.selected)?.name
- const defaultGroupName = (node.schemaType.groups || []).find((group) => group.default)?.name
+ const schemaFieldGroup = (schemaField && castArray(schemaField.group)) || []
const inSelectedGroup =
selectedGroupName &&
- (selectedGroupName === ALL_FIELDS_GROUP.name ||
- (schemaField && castArray(schemaField.group).includes(selectedGroupName)))
+ (selectedGroupName === ALL_FIELDS_GROUP.name || schemaFieldGroup.includes(selectedGroupName))
const ops: (ExpandFieldSetOperation | SetActiveGroupOperation)[] = []
if (!inSelectedGroup) {
+ const groupName =
+ node.groups.find((group) => schemaFieldGroup.includes(group.name))?.name ||
+ ALL_FIELDS_GROUP.name
ops.push({
type: 'setSelectedGroup',
path: node.path,
- groupName: defaultGroupName || ALL_FIELDS_GROUP.name,
+ groupName,
})
}
diff --git a/packages/sanity/src/core/form/store/utils/immutableReconcile.ts b/packages/sanity/src/core/form/store/utils/immutableReconcile.ts
index 095c1a84dbc8..8e8da4d12f19 100644
--- a/packages/sanity/src/core/form/store/utils/immutableReconcile.ts
+++ b/packages/sanity/src/core/form/store/utils/immutableReconcile.ts
@@ -54,12 +54,14 @@ function _immutableReconcile(
assertType>(previous)
assertType>(next)
- const nextKeys = Object.keys(next)
- let allEqual = Object.keys(previous).length === nextKeys.length
+ const nextKeys = Object.getOwnPropertyNames(next)
+ let allEqual = Object.getOwnPropertyNames(previous).length === nextKeys.length
const result: Record = {}
parents.set(next, result)
for (const key of nextKeys) {
- const nextValue = _immutableReconcile(previous[key], next[key]!, parents)
+ const nextValue = next.propertyIsEnumerable(key)
+ ? _immutableReconcile(previous[key], next[key]!, parents)
+ : next[key]
if (nextValue !== previous[key]) {
allEqual = false
}