Skip to content

Commit c531374

Browse files
@W-18685092@ @W-18685121@ Chakra v3 - update checkout shipping address and shipping option selection (#2690)
* Apply initial changes * Radio card changes * More radio card adjustments * Fix shipping option selection * Use value instead of selectedAddress for isSelected * Lint * Remove extra comment --------- Co-authored-by: unandyala <unandyala@salesforce.com>
1 parent b74c81d commit c531374

File tree

12 files changed

+158
-106
lines changed

12 files changed

+158
-106
lines changed

packages/extension-chakra-storefront/src/components/action-card/index.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ const ActionCard = ({
5353
{onEdit && (
5454
<Button
5555
onClick={onEdit}
56-
variant="link"
56+
variant="link-blue"
5757
size="sm"
5858
ref={editBtnRef}
5959
aria-label={editBtnLabel}
@@ -63,7 +63,7 @@ const ActionCard = ({
6363
)}
6464
{onRemove && (
6565
<Button
66-
variant="link"
66+
variant="link-red"
6767
size="sm"
6868
colorScheme="red"
6969
onClick={handleRemove}

packages/extension-chakra-storefront/src/components/field/index.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ const Field = ({
7070
endElement={
7171
type === 'password' ? (
7272
<IconButton
73-
variant="ghosted"
73+
variant="ghost"
7474
aria-label={passwordIconLabel}
7575
onClick={() => setHidePassword(!hidePassword)}
7676
>
@@ -113,6 +113,7 @@ const Field = ({
113113
<>
114114
<NativeSelect.Root ref={ref} value={value} {..._inputProps}>
115115
<NativeSelect.Field
116+
value={value || ''}
116117
onChange={onChange}
117118
placeholder={placeholder}
118119
>

packages/extension-chakra-storefront/src/components/forms/address-fields.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const AddressFields = ({
3535

3636
return (
3737
<Stack
38-
spacing={5}
38+
gap={5}
3939
aria-label={intl.formatMessage(formTitleAriaLabel)}
4040
tabIndex="0"
4141
ref={addressFormRef}

packages/extension-chakra-storefront/src/components/forms/form-action-buttons.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const FormActionButtons = ({
2222
onCancel = () => {}
2323
}) => {
2424
return (
25-
<Stack direction={{base: 'column', lg: 'row-reverse'}} spacing={4}>
25+
<Stack direction={{base: 'column', lg: 'row-reverse'}} gap={4}>
2626
<Button type="submit" minWidth={28} {...saveButtonProps}>
2727
{saveButtonLabel ? (
2828
<FormattedMessage {...saveButtonLabel} />

packages/extension-chakra-storefront/src/components/radio-card/index.jsx

Lines changed: 43 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6,70 +6,65 @@
66
*/
77
import React from 'react'
88
import PropTypes from 'prop-types'
9-
import {Box, useRadio, useRadioGroup} from '@chakra-ui/react'
9+
import {Box, RadioCard as ChakraRadioCard, useSlotRecipe} from '@chakra-ui/react'
1010
import {CheckIcon} from '../../components/icons'
1111

1212
const RadioCardGroupContext = React.createContext()
1313

1414
export const RadioCard = (props) => {
1515
const getRadioGroupProps = React.useContext(RadioCardGroupContext)
16-
const {getInputProps, getRadioProps} = useRadio(getRadioGroupProps(props))
16+
const {value, children, isSelected} = getRadioGroupProps(props)
17+
const recipe = useSlotRecipe({key: 'radioCard'})
18+
const styles = recipe()
1719

18-
const input = getInputProps()
19-
const checkbox = getRadioProps()
2020
return (
21-
<Box as="label">
22-
<input {...input} />
23-
<Box
24-
{...checkbox}
25-
aria-hidden={false}
26-
position="relative"
27-
cursor="pointer"
28-
border="1px solid"
29-
borderColor="gray.200"
30-
borderRadius="base"
31-
height="full"
32-
_checked={{
33-
borderColor: 'blue.600'
34-
}}
35-
_focus={{
36-
boxShadow: 'outline'
37-
}}
38-
px={4}
39-
py={4}
40-
>
41-
{input.checked && (
42-
<Box
43-
position="absolute"
44-
top={0}
45-
right={0}
46-
w={0}
47-
h={0}
48-
borderStyle="solid"
49-
borderWidth="0 38px 38px 0"
50-
borderColor="transparent"
51-
borderRightColor="blue.600"
52-
>
53-
<CheckIcon color="white" position="absolute" right="-40px" top="1px" />
54-
</Box>
55-
)}
56-
57-
{props.children}
58-
</Box>
59-
</Box>
21+
<ChakraRadioCard.Item key={value} value={value} css={styles.item}>
22+
{/* TODO: Use the _checked state of the radio card instead of isSelected */}
23+
{isSelected && (
24+
<Box
25+
position="absolute"
26+
top={0}
27+
right={0}
28+
w={0}
29+
h={0}
30+
borderStyle="solid"
31+
borderWidth="0 38px 38px 0"
32+
borderColor="transparent"
33+
borderRightColor="blue.600"
34+
>
35+
<CheckIcon color="white" position="absolute" right="-40px" top="1px" />
36+
</Box>
37+
)}
38+
<ChakraRadioCard.ItemHiddenInput />
39+
<ChakraRadioCard.ItemControl>{children}</ChakraRadioCard.ItemControl>
40+
</ChakraRadioCard.Item>
6041
)
6142
}
6243

6344
export const RadioCardGroup = (props) => {
64-
const {getRootProps, getRadioProps} = useRadioGroup(props)
65-
const group = getRootProps()
45+
const {value, onValueChange, ...groupProps} = props
46+
const recipe = useSlotRecipe({key: 'radioCard'})
47+
const styles = recipe()
6648

6749
return (
68-
<RadioCardGroupContext.Provider value={getRadioProps}>
69-
<Box {...group}>{props.children}</Box>
50+
<RadioCardGroupContext.Provider
51+
value={(itemProps) => ({...itemProps, value: itemProps.value})}
52+
>
53+
<ChakraRadioCard.Root
54+
value={value}
55+
onValueChange={onValueChange}
56+
css={styles.root}
57+
{...groupProps}
58+
>
59+
{props.children}
60+
</ChakraRadioCard.Root>
7061
</RadioCardGroupContext.Provider>
7162
)
7263
}
7364

7465
RadioCard.propTypes = {children: PropTypes.any}
75-
RadioCardGroup.propTypes = {children: PropTypes.any}
66+
RadioCardGroup.propTypes = {
67+
value: PropTypes.any,
68+
onValueChange: PropTypes.func,
69+
children: PropTypes.any
70+
}

packages/extension-chakra-storefront/src/pages/checkout/partials/shipping-address-selection.jsx

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,14 @@ const ShippingAddressEditForm = ({
5050
})}
5151
data-testid="sf-shipping-address-edit-form"
5252
>
53-
<Stack spacing={6}>
53+
<Stack gap={6}>
5454
{hasSavedAddresses && !isBillingAddress && (
5555
<Heading as="h3" size="sm">
5656
{title}
5757
</Heading>
5858
)}
5959

60-
<Stack spacing={6}>
60+
<Stack gap={6}>
6161
<AddressFields
6262
form={form}
6363
formTitleAriaLabel={formTitleAriaLabel}
@@ -208,7 +208,6 @@ const ShippingAddressSelection = ({
208208
}
209209

210210
const address = customer.addresses.find((addr) => addr.addressId === addressId)
211-
212211
form.reset({...address})
213212
}
214213

@@ -270,20 +269,22 @@ const ShippingAddressSelection = ({
270269
}
271270
return (
272271
<form onSubmit={form.handleSubmit(submitForm)}>
273-
<Stack spacing={4}>
272+
<Stack gap={4}>
274273
{hasSavedAddresses && !isBillingAddress && (
275274
<Controller
276275
name="addressId"
277276
defaultValue=""
278277
control={form.control}
279278
rules={{required: !isEditingAddress}}
280-
render={({field: {value}}) => (
281-
<RadioCardGroup value={value} onChange={handleAddressIdSelection}>
282-
<SimpleGrid
283-
columns={[1, 1, 2]}
284-
spacing={4}
285-
gridAutoFlow="row dense"
286-
>
279+
render={({field: {value, onChange}}) => (
280+
<RadioCardGroup
281+
value={value}
282+
onValueChange={(selected) => {
283+
onChange(selected.value)
284+
handleAddressIdSelection(selected.value)
285+
}}
286+
>
287+
<SimpleGrid columns={[1, 1, 2]} gap={4} gridAutoFlow="row dense">
287288
{customer.addresses?.map((address, index) => {
288289
const editLabel = formatMessage(
289290
{
@@ -302,7 +303,10 @@ const ShippingAddressSelection = ({
302303
)
303304
return (
304305
<React.Fragment key={address.addressId}>
305-
<RadioCard value={address.addressId}>
306+
<RadioCard
307+
value={address.addressId}
308+
isSelected={address.addressId === value}
309+
>
306310
<ActionCard
307311
padding={0}
308312
border="none"
@@ -361,7 +365,7 @@ const ShippingAddressSelection = ({
361365
color="blue.600"
362366
height={['44px', '44px', '167px']}
363367
rounded="base"
364-
fontWeight="medium"
368+
fontWeight="semibold"
365369
leftIcon={<PlusIcon boxSize={'15px'} />}
366370
onClick={toggleAddressEdit}
367371
>

packages/extension-chakra-storefront/src/pages/checkout/partials/shipping-address.jsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,12 @@ export default function ShippingAddress() {
120120
})}
121121
>
122122
<ToggleCardEdit>
123-
TODO
124-
{/* <ShippingAddressSelection */}
125-
{/* selectedAddress={selectedShippingAddress} */}
126-
{/* submitButtonLabel={submitButtonMessage} */}
127-
{/* onSubmit={submitAndContinue} */}
128-
{/* formTitleAriaLabel={shippingAddressAriaLabel} */}
129-
{/* /> */}
123+
<ShippingAddressSelection
124+
selectedAddress={selectedShippingAddress}
125+
submitButtonLabel={submitButtonMessage}
126+
onSubmit={submitAndContinue}
127+
formTitleAriaLabel={shippingAddressAriaLabel}
128+
/>
130129
</ToggleCardEdit>
131130
{selectedShippingAddress && (
132131
<ToggleCardSummary>

packages/extension-chakra-storefront/src/pages/checkout/partials/shipping-options.jsx

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77
import React, {useEffect} from 'react'
88
import {FormattedMessage, FormattedNumber, useIntl} from 'react-intl'
9-
import {Box, Button, Container, Flex, Radio, RadioGroup, Stack, Text} from '@chakra-ui/react'
9+
import {Box, Button, Container, Flex, HStack, RadioGroup, Stack, Text} from '@chakra-ui/react'
1010
import {useForm, Controller} from 'react-hook-form'
1111
import {useCheckout} from '../../../pages/checkout/util/checkout-context'
1212
import {ChevronDownIcon} from '../../../components/icons'
@@ -124,32 +124,57 @@ export default function ShippingOptions() {
124124
onSubmit={form.handleSubmit(submitForm)}
125125
data-testid="sf-checkout-shipping-options-form"
126126
>
127-
<Stack spacing={6}>
127+
<Stack gap={6}>
128128
{shippingMethods?.applicableShippingMethods && (
129129
<Controller
130130
name="shippingMethodId"
131131
control={form.control}
132132
defaultValue=""
133133
render={({field: {value, onChange}}) => (
134-
<RadioGroup
134+
<RadioGroup.Root
135135
name="shipping-options-radiogroup"
136136
value={value}
137-
onChange={onChange}
137+
onValueChange={(selected) => {
138+
onChange(selected.value) // Chakra v3 radio returns the selected id in an object with a value property
139+
}}
138140
>
139-
<Stack spacing={5}>
141+
<Stack gap={5}>
140142
{shippingMethods.applicableShippingMethods.map(
141143
(opt) => (
142-
<Radio value={opt.id} key={opt.id}>
144+
<RadioGroup.Item value={opt.id} key={opt.id}>
145+
<RadioGroup.ItemHiddenInput />
146+
<RadioGroup.ItemIndicator />
143147
<Flex justify="space-between" w="full">
144-
<Box>
145-
<Text>{opt.name}</Text>
146-
<Text
147-
fontSize="sm"
148-
color="gray.600"
149-
>
150-
{opt.description}
151-
</Text>
152-
</Box>
148+
<HStack>
149+
<Box>
150+
<RadioGroup.ItemText>
151+
{opt.name}
152+
</RadioGroup.ItemText>
153+
<Text
154+
fontSize="sm"
155+
color="gray.600"
156+
>
157+
{opt.description}
158+
</Text>
159+
{opt.shippingPromotions?.map(
160+
(promo) => {
161+
return (
162+
<Text
163+
key={
164+
promo.promotionId
165+
}
166+
fontSize="sm"
167+
color="green.600"
168+
>
169+
{
170+
promo.calloutMsg
171+
}
172+
</Text>
173+
)
174+
}
175+
)}
176+
</Box>
177+
</HStack>
153178
<Text fontWeight="bold">
154179
<FormattedNumber
155180
value={opt.price}
@@ -158,29 +183,18 @@ export default function ShippingOptions() {
158183
/>
159184
</Text>
160185
</Flex>
161-
162-
{opt.shippingPromotions?.map((promo) => {
163-
return (
164-
<Text
165-
key={promo.promotionId}
166-
fontSize="sm"
167-
color="green.600"
168-
>
169-
{promo.calloutMsg}
170-
</Text>
171-
)
172-
})}
173-
</Radio>
186+
</RadioGroup.Item>
174187
)
175188
)}
176189
</Stack>
177-
</RadioGroup>
190+
</RadioGroup.Root>
178191
)}
179192
/>
180193
)}
181194

182195
<Box>
183-
<Button variant="link" size="sm" rightIcon={<ChevronDownIcon />}>
196+
{/* TODO: Get the rightIcon to display */}
197+
<Button variant="link-blue" size="sm" rightIcon={<ChevronDownIcon />}>
184198
<FormattedMessage
185199
defaultMessage="Do you want to send this as a gift?"
186200
id="shipping_options.action.send_as_a_gift"

packages/extension-chakra-storefront/src/theme/components/base/native-select.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ export default defineSlotRecipe({
1515
filled: {
1616
field: {
1717
border: '2px solid',
18-
borderColor: 'transparent',
19-
background: 'red.200',
18+
borderColor: 'gray.100',
2019
_hover: {
2120
background: 'gray.200'
2221
},
@@ -30,7 +29,7 @@ export default defineSlotRecipe({
3029
}
3130
},
3231
indicator: {
33-
color: 'white'
32+
color: 'black'
3433
}
3534
}
3635
}

0 commit comments

Comments
 (0)