Skip to content

Commit 03027bb

Browse files
authored
Merge pull request #2620 from graphcommerce-org/feat/signup-form-fieldsets-render-props
feat(magento-customer): forward fieldsets + render props on SignUpForm
2 parents a090647 + c8d56e1 commit 03027bb

4 files changed

Lines changed: 40 additions & 8 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
'@graphcommerce/magento-customer': minor
3+
'@graphcommerce/magento-store': patch
4+
---
5+
6+
`SignUpForm` now accepts `fieldsets` and `render` props (mirroring `CustomerUpdateForm`), so consumers can group dynamic customer attributes into custom labelled sections via `AttributesFormAutoLayout`. Defaults to the existing `[nameFieldset(attributes)]` / `CustomerAttributeField` behaviour, so unchanged for projects that don't supply the props.
7+
8+
This avoids the unstyled, untranslated `Other` fallback header that `AttributesFormAutoLayout` adds whenever attributes don't fit any registered fieldset — projects that extend the customer schema (e.g. with a `club` attribute) can now declare their own fieldset alongside `nameFieldset`.
9+
10+
The fallback header itself in `AttributesFormAutoLayout` is now wrapped in `<Trans>Other</Trans>` so it picks up project translations instead of rendering as a hardcoded English string.
11+
12+
Bug fix in `nameFieldset`: when a store doesn't register `dob`/`gender` on the registration form, the `additional` row was empty and the helper produced `grid-template-areas: "firstname lastname" ""`, which is invalid CSS and made the whole declaration fall back to the default single-column layout — firstname/lastname stacked on separate rows even at md+. Empty rows are now filtered out, so the side-by-side md layout works as intended.

packages/magento-customer/components/CustomerForms/nameFieldset.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,21 @@ export function nameFieldset(
1919

2020
const additional = extractAttributes(attributes, ['dob', 'gender'])[0].map((f) => f.code)
2121

22+
// Skip empty rows — an empty `""` row produces invalid `grid-template-areas`
23+
// and silently makes the whole declaration fall back to the default
24+
// single-column layout. Hit when a store doesn't register `dob`/`gender` on
25+
// the registration form, leaving `additional` empty.
26+
const rows = [nameFields, additional]
27+
.filter((row) => row.length > 0)
28+
.map((row) => `"${row.join(' ')}"`)
29+
2230
return {
2331
label: withLabel ? <Trans>Name</Trans> : undefined,
2432
gridAreas: [...nameFields, ...additional],
2533
// xs is shown in one column by default
2634
sx: {
2735
gridTemplateAreas: {
28-
md: [`"${nameFields.join(' ')}"`, `"${additional.join(' ')}"`].join(' '),
36+
md: rows.join(' '),
2937
},
3038
},
3139
}

packages/magento-customer/components/SignUpForm/SignUpForm.tsx

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { FormPersist, PasswordRepeatElement, SwitchElement } from '@graphcommerce/ecommerce-ui'
22
import { useQuery } from '@graphcommerce/graphql'
3-
import { AttributesFormAutoLayout, StoreConfigDocument } from '@graphcommerce/magento-store'
3+
import {
4+
AttributesFormAutoLayout,
5+
StoreConfigDocument,
6+
type AttributeFormAutoLayoutProps,
7+
} from '@graphcommerce/magento-store'
48
import { magentoVersion } from '@graphcommerce/next-config/config'
59
import { Button, FormActions, FormRow } from '@graphcommerce/next-ui'
610
import type { UseFormClearErrors, UseFormSetError } from '@graphcommerce/react-hook-form'
@@ -11,18 +15,24 @@ import { useSignInForm } from '../../hooks/useSignInForm'
1115
import { ApolloCustomerErrorSnackbar } from '../ApolloCustomerError/ApolloCustomerErrorSnackbar'
1216
import { CustomerAttributeField } from '../CustomerForms/CustomerAttributeField'
1317
import { nameFieldset } from '../CustomerForms/nameFieldset'
14-
import { useCustomerCreateForm } from '../CustomerForms/useCustomerCreateForm'
18+
import {
19+
useCustomerCreateForm,
20+
type CreateCustomerFormValues,
21+
} from '../CustomerForms/useCustomerCreateForm'
1522
import { NameFields } from '../NameFields/NameFields'
1623
import { ValidatedPasswordElement } from '../ValidatedPasswordElement/ValidatedPasswordElement'
1724

18-
type SignUpFormProps = {
25+
export type SignUpFormProps = Pick<
26+
AttributeFormAutoLayoutProps<CreateCustomerFormValues, 'CustomerAttributeMetadata'>,
27+
'fieldsets' | 'render'
28+
> & {
1929
email?: string
2030
setError: UseFormSetError<{ email?: string; requestedMode?: 'signin' | 'signup' }>
2131
clearErrors: UseFormClearErrors<{ email?: string; requestedMode?: 'signin' | 'signup' }>
2232
}
2333

2434
export function SignUpForm(props: SignUpFormProps) {
25-
const { email, setError, clearErrors } = props
35+
const { email, setError, clearErrors, fieldsets, render } = props
2636

2737
const storeConfig = useQuery(StoreConfigDocument)
2838

@@ -109,8 +119,8 @@ export function SignUpForm(props: SignUpFormProps) {
109119
<AttributesFormAutoLayout
110120
attributes={attributes}
111121
control={control}
112-
render={CustomerAttributeField}
113-
fieldsets={[nameFieldset(attributes)]}
122+
render={render ?? CustomerAttributeField}
123+
fieldsets={fieldsets ?? [nameFieldset(attributes)]}
114124
/>
115125
)}
116126

packages/magento-store/components/AttributeForm/AttributesFormAutoLayout.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
type SectionContainerProps,
66
} from '@graphcommerce/next-ui'
77
import type { Control, FieldValues } from '@graphcommerce/react-hook-form'
8+
import { Trans } from '@lingui/react/macro'
89
import { Box, type SxProps, type Theme } from '@mui/material'
910
import { AttributeFormField, type AttributeFormFieldProps } from './AttributeFormField'
1011
import type {
@@ -54,7 +55,8 @@ export function AttributesFormAutoLayout<
5455
.filter(nonNullable),
5556
}))
5657

57-
if (itemsRemaining.length > 0) byFieldSet.push({ label: 'Other', attributes: itemsRemaining })
58+
if (itemsRemaining.length > 0)
59+
byFieldSet.push({ label: <Trans>Other</Trans>, attributes: itemsRemaining })
5860

5961
return byFieldSet.map((fieldSet) => {
6062
const key = fieldSet.attributes.map((fieldName) => fieldName.gridArea).join('-')

0 commit comments

Comments
 (0)