@graphcommerce/magento-cart-shipping-method 3.0.27 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,54 @@
1
1
  # Change Log
2
2
 
3
+ ## 3.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1515](https://github.com/graphcommerce-org/graphcommerce/pull/1515) [`371e6cf52`](https://github.com/graphcommerce-org/graphcommerce/commit/371e6cf52916a3b6c44192bd40cc8271bd608832) Thanks [@mikekeehnen](https://github.com/mikekeehnen)! - - Shipping method UI improvements in checkout, like working ripple effect, auto select and other styling changes.
8
+ - Added new inline button variant
9
+
10
+ * [#1518](https://github.com/graphcommerce-org/graphcommerce/pull/1518) [`4143483f3`](https://github.com/graphcommerce-org/graphcommerce/commit/4143483f37c038d2bbf218be2685e27a31a35745) Thanks [@mikekeehnen](https://github.com/mikekeehnen)! - New ActionCardListForm implementation for Payment Methods
11
+
12
+ ### Patch Changes
13
+
14
+ - Updated dependencies [[`371e6cf52`](https://github.com/graphcommerce-org/graphcommerce/commit/371e6cf52916a3b6c44192bd40cc8271bd608832), [`4143483f3`](https://github.com/graphcommerce-org/graphcommerce/commit/4143483f37c038d2bbf218be2685e27a31a35745)]:
15
+ - @graphcommerce/magento-cart-shipping-address@3.2.0
16
+ - @graphcommerce/next-ui@4.10.0
17
+ - @graphcommerce/magento-cart@4.4.4
18
+ - @graphcommerce/framer-scroller@2.1.17
19
+ - @graphcommerce/magento-store@4.2.11
20
+
21
+ ## 3.1.0
22
+
23
+ ### Minor Changes
24
+
25
+ - [#1503](https://github.com/graphcommerce-org/graphcommerce/pull/1503) [`a9213f1f5`](https://github.com/graphcommerce-org/graphcommerce/commit/a9213f1f5a410d217768386ccb6d9b5ce7bd5782) Thanks [@mikekeehnen](https://github.com/mikekeehnen)! - Bug fixes for shipping methods in /checkout
26
+
27
+ ### Patch Changes
28
+
29
+ - [#1490](https://github.com/graphcommerce-org/graphcommerce/pull/1490) [`d311ef48b`](https://github.com/graphcommerce-org/graphcommerce/commit/d311ef48bb3e97806d992af5516d6b7f183ec9cb) Thanks [@paales](https://github.com/paales)! - upgraded packages
30
+
31
+ - Updated dependencies [[`a9213f1f5`](https://github.com/graphcommerce-org/graphcommerce/commit/a9213f1f5a410d217768386ccb6d9b5ce7bd5782), [`ddb6d6329`](https://github.com/graphcommerce-org/graphcommerce/commit/ddb6d6329bfad361b2fbe96402ca2bfc0ab3d98c), [`d311ef48b`](https://github.com/graphcommerce-org/graphcommerce/commit/d311ef48bb3e97806d992af5516d6b7f183ec9cb)]:
32
+ - @graphcommerce/magento-cart-shipping-address@3.1.0
33
+ - @graphcommerce/next-ui@4.9.0
34
+ - @graphcommerce/framer-scroller@2.1.16
35
+ - @graphcommerce/graphql@3.2.1
36
+ - @graphcommerce/image@3.1.7
37
+ - @graphcommerce/magento-cart@4.4.3
38
+ - @graphcommerce/magento-store@4.2.10
39
+ - @graphcommerce/react-hook-form@3.2.2
40
+
41
+ ## 3.0.28
42
+
43
+ ### Patch Changes
44
+
45
+ - Updated dependencies [[`0ab7c5465`](https://github.com/graphcommerce-org/graphcommerce/commit/0ab7c5465441cba9bf8cd185a6790ce2f443f4ed)]:
46
+ - @graphcommerce/framer-scroller@2.1.15
47
+ - @graphcommerce/next-ui@4.8.4
48
+ - @graphcommerce/magento-cart@4.4.2
49
+ - @graphcommerce/magento-cart-shipping-address@3.0.27
50
+ - @graphcommerce/magento-store@4.2.9
51
+
3
52
  ## 3.0.27
4
53
 
5
54
  ### Patch Changes
@@ -0,0 +1,45 @@
1
+ import { Money } from '@graphcommerce/magento-store'
2
+ import { ActionCard } from '@graphcommerce/next-ui'
3
+ import { ActionCardItemRenderProps } from '@graphcommerce/next-ui/ActionCard/ActionCardListForm'
4
+ import { Trans } from '@lingui/react'
5
+ import { Box, Button } from '@mui/material'
6
+ import { AvailableShippingMethodFragment } from '../../AvailableShippingMethod/AvailableShippingMethod.gql'
7
+
8
+ type ShippingMethodActionCardProps = ActionCardItemRenderProps<
9
+ AvailableShippingMethodFragment | null | undefined
10
+ >
11
+
12
+ export function ShippingMethodActionCard(props: ShippingMethodActionCardProps) {
13
+ const { available, amount, error_message, carrier_title, carrier_code, onReset, ...cardProps } =
14
+ props
15
+ let { hidden = false } = props
16
+
17
+ const isFree = amount && amount.value === 0
18
+
19
+ if (carrier_code !== 'freeshipping') hidden = !available ? true : hidden
20
+
21
+ return (
22
+ <ActionCard
23
+ {...cardProps}
24
+ hidden={hidden}
25
+ title={carrier_title}
26
+ details={error_message}
27
+ action={
28
+ <Button
29
+ variant='inline'
30
+ color='secondary'
31
+ sx={{ display: available ? undefined : 'none' }}
32
+ disableRipple
33
+ >
34
+ <Trans id='Select' />
35
+ </Button>
36
+ }
37
+ price={!isFree ? <Money {...amount} /> : <Box sx={{ color: '#05C642' }}>Free</Box>}
38
+ reset={
39
+ <Button variant='inline' color='secondary' onClick={onReset} disableRipple size='small'>
40
+ <Trans id='Change' />
41
+ </Button>
42
+ }
43
+ />
44
+ )
45
+ }
@@ -0,0 +1,111 @@
1
+ import {
2
+ ApolloCartErrorAlert,
3
+ useCartQuery,
4
+ useFormGqlMutationCart,
5
+ } from '@graphcommerce/magento-cart'
6
+ import { Form, FormHeader } from '@graphcommerce/next-ui'
7
+ import {
8
+ ActionCardItemBase,
9
+ ActionCardItemRenderProps,
10
+ ActionCardListForm,
11
+ } from '@graphcommerce/next-ui/ActionCard/ActionCardListForm'
12
+ import {
13
+ useFormCompose,
14
+ UseFormComposeOptions,
15
+ useFormPersist,
16
+ } from '@graphcommerce/react-hook-form'
17
+ import { i18n } from '@lingui/core'
18
+ import { Trans } from '@lingui/react'
19
+ import { useEffect, useMemo, VFC } from 'react'
20
+ import { GetShippingMethodsDocument } from './GetShippingMethods.gql'
21
+ import { ShippingMethodActionCard } from './ShippingMethodActionCard'
22
+ import {
23
+ ShippingMethodFormDocument,
24
+ ShippingMethodFormMutation,
25
+ ShippingMethodFormMutationVariables,
26
+ } from './ShippingMethodForm.gql'
27
+
28
+ export type ShippingMethodFormProps = Pick<UseFormComposeOptions, 'step'>
29
+
30
+ export function ShippingMethodForm(props: ShippingMethodFormProps) {
31
+ const { step } = props
32
+ const { data: cartQuery, loading } = useCartQuery(GetShippingMethodsDocument)
33
+ const currentAddress = cartQuery?.cart?.shipping_addresses?.[0]
34
+ const available = currentAddress?.available_shipping_methods
35
+ const selected = currentAddress?.selected_shipping_method
36
+ const carrier = selected?.carrier_code ?? available?.[0]?.carrier_code
37
+ const method = selected?.method_code ?? available?.[0]?.method_code ?? undefined
38
+ const carrierMethod = `${carrier}-${method}`
39
+
40
+ const sortedAvailableShippingMethods = useMemo(
41
+ () =>
42
+ [
43
+ ...(currentAddress?.available_shipping_methods ?? []),
44
+ // eslint-disable-next-line no-nested-ternary
45
+ ].sort((a, b) => (a === b ? 0 : a ? -1 : 1)),
46
+ [currentAddress?.available_shipping_methods],
47
+ )
48
+
49
+ const form = useFormGqlMutationCart<
50
+ ShippingMethodFormMutation,
51
+ ShippingMethodFormMutationVariables & { carrierMethod?: string }
52
+ >(ShippingMethodFormDocument, {
53
+ defaultValues: { carrierMethod, carrier, method },
54
+ onBeforeSubmit: (variables) => {
55
+ const splitCarrierMethod = variables?.carrierMethod?.split('-')
56
+ return {
57
+ ...variables,
58
+ carrier: splitCarrierMethod?.[0] ?? available?.[0]?.carrier_code ?? '',
59
+ method: splitCarrierMethod?.[1] ?? available?.[0]?.method_code ?? '',
60
+ }
61
+ },
62
+ })
63
+
64
+ const { handleSubmit, control, error, setValue } = form
65
+ const submit = handleSubmit(() => {})
66
+
67
+ useFormPersist({ form, name: 'ShippingMethodForm' })
68
+ useFormCompose({ form, step, submit, key: 'ShippingMethodForm' })
69
+
70
+ useEffect(() => {
71
+ const availableMethods = sortedAvailableShippingMethods.filter((m) => m?.available)
72
+ if (availableMethods.length === 1) {
73
+ setValue(
74
+ 'carrierMethod',
75
+ `${availableMethods[0]?.carrier_code}-${availableMethods[0]?.method_code}`,
76
+ )
77
+ }
78
+ }, [
79
+ carrier,
80
+ method,
81
+ selected?.carrier_code,
82
+ selected?.method_code,
83
+ setValue,
84
+ sortedAvailableShippingMethods,
85
+ ])
86
+
87
+ return (
88
+ <>
89
+ {!loading && sortedAvailableShippingMethods.length > 0 && (
90
+ <FormHeader variant='h5' sx={{ marginBottom: 0 }}>
91
+ <Trans id='Shipping method' />
92
+ </FormHeader>
93
+ )}
94
+
95
+ <Form onSubmit={submit} noValidate>
96
+ <ActionCardListForm
97
+ control={control}
98
+ name='carrierMethod'
99
+ errorMessage={i18n._(/* i18n */ `Please select a shipping method`)}
100
+ items={sortedAvailableShippingMethods.filter(Boolean).map((sortedMethod) => ({
101
+ ...sortedMethod,
102
+ disabled: !sortedMethod?.available,
103
+ value: `${sortedMethod?.carrier_code}-${sortedMethod?.method_code}`,
104
+ }))}
105
+ render={ShippingMethodActionCard as VFC<ActionCardItemRenderProps<ActionCardItemBase>>}
106
+ />
107
+ <ApolloCartErrorAlert error={error} />
108
+ </Form>
109
+ </>
110
+ )
111
+ }
package/index.ts CHANGED
@@ -1,4 +1,3 @@
1
1
  export * from './Api/AvailableShippingMethods.gql'
2
2
  export * from './Api/ShippingMethodSelected.gql'
3
-
4
- export * from './ShippingMethodForm/ShippingMethodForm'
3
+ export * from './components/ShippingMethodForm/ShippingMethodForm'
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@graphcommerce/magento-cart-shipping-method",
3
3
  "homepage": "https://www.graphcommerce.org/",
4
4
  "repository": "github:graphcommerce-org/graphcommerce",
5
- "version": "3.0.27",
5
+ "version": "3.2.0",
6
6
  "sideEffects": false,
7
7
  "prettier": "@graphcommerce/prettier-config-pwa",
8
8
  "eslintConfig": {
@@ -12,29 +12,29 @@
12
12
  }
13
13
  },
14
14
  "devDependencies": {
15
- "@graphcommerce/eslint-config-pwa": "^4.1.7",
15
+ "@graphcommerce/eslint-config-pwa": "^4.1.8",
16
16
  "@graphcommerce/prettier-config-pwa": "^4.0.6",
17
17
  "@graphcommerce/typescript-config-pwa": "^4.0.3",
18
18
  "@playwright/test": "^1.21.1",
19
19
  "type-fest": "^2.12.2"
20
20
  },
21
21
  "dependencies": {
22
- "@graphcommerce/framer-scroller": "2.1.14",
23
- "@graphcommerce/graphql": "3.2.0",
24
- "@graphcommerce/image": "3.1.6",
25
- "@graphcommerce/magento-cart": "4.4.1",
26
- "@graphcommerce/magento-cart-shipping-address": "3.0.26",
27
- "@graphcommerce/magento-store": "4.2.8",
28
- "@graphcommerce/next-ui": "4.8.3",
29
- "@graphcommerce/react-hook-form": "3.2.1"
22
+ "@graphcommerce/framer-scroller": "2.1.17",
23
+ "@graphcommerce/graphql": "3.2.1",
24
+ "@graphcommerce/image": "3.1.7",
25
+ "@graphcommerce/magento-cart": "4.4.4",
26
+ "@graphcommerce/magento-cart-shipping-address": "3.2.0",
27
+ "@graphcommerce/magento-store": "4.2.11",
28
+ "@graphcommerce/next-ui": "4.10.0",
29
+ "@graphcommerce/react-hook-form": "3.2.2"
30
30
  },
31
31
  "peerDependencies": {
32
32
  "@lingui/react": "^3.13.2",
33
33
  "@lingui/core": "^3.13.2",
34
34
  "@mui/material": "5.5.3",
35
35
  "framer-motion": "^6.2.4",
36
- "next": "12.1.2",
37
- "react": "^17.0.2",
38
- "react-dom": "^17.0.2"
36
+ "next": "^12.1.2",
37
+ "react": "^18.0.0",
38
+ "react-dom": "^18.0.0"
39
39
  }
40
40
  }
@@ -1,244 +0,0 @@
1
- import { Scroller, ScrollerButton, ScrollerProvider } from '@graphcommerce/framer-scroller'
2
- import {
3
- ApolloCartErrorAlert,
4
- useCartQuery,
5
- useFormGqlMutationCart,
6
- } from '@graphcommerce/magento-cart'
7
- import {
8
- Form,
9
- FormRow,
10
- iconChevronLeft,
11
- iconChevronRight,
12
- IconSvg,
13
- extendableComponent,
14
- } from '@graphcommerce/next-ui'
15
- import { Controller, useFormCompose, UseFormComposeOptions } from '@graphcommerce/react-hook-form'
16
- import { i18n } from '@lingui/core'
17
- import { Trans } from '@lingui/react'
18
- import { FormControl, Alert, Box } from '@mui/material'
19
- import { AvailableShippingMethod } from '../AvailableShippingMethod/AvailableShippingMethod'
20
- import { GetShippingMethodsDocument } from './GetShippingMethods.gql'
21
- import {
22
- ShippingMethodFormDocument,
23
- ShippingMethodFormMutation,
24
- ShippingMethodFormMutationVariables,
25
- } from './ShippingMethodForm.gql'
26
-
27
- export type ShippingMethodFormProps = Pick<UseFormComposeOptions, 'step'>
28
-
29
- type OwnerProps = {
30
- itemCount?: number
31
- }
32
-
33
- const name = 'ShippingMethodForm' as const
34
- const parts = ['root', 'alert', 'buttonRoot', 'buttonContainer', 'scrollerRoot'] as const
35
- const { withState } = extendableComponent<OwnerProps, typeof name, typeof parts>(name, parts)
36
-
37
- export function ShippingMethodForm(props: ShippingMethodFormProps) {
38
- const { step } = props
39
- const { data: cartQuery } = useCartQuery(GetShippingMethodsDocument)
40
-
41
- const currentAddress = cartQuery?.cart?.shipping_addresses?.[0]
42
- const available = currentAddress?.available_shipping_methods
43
- const selected = currentAddress?.selected_shipping_method
44
- const carrier = selected?.carrier_code ?? available?.[0]?.carrier_code
45
- const method = selected?.method_code ?? available?.[0]?.method_code ?? undefined
46
- const carrierMethod = carrier && method ? `${carrier}-${method}` : undefined
47
-
48
- const sortedAvailableShippingMethods = [
49
- ...(currentAddress?.available_shipping_methods ?? []),
50
- // eslint-disable-next-line no-nested-ternary
51
- ].sort((a, b) => (a === b ? 0 : a ? -1 : 1))
52
-
53
- const form = useFormGqlMutationCart<
54
- ShippingMethodFormMutation,
55
- ShippingMethodFormMutationVariables & { carrierMethod?: string }
56
- >(ShippingMethodFormDocument, {
57
- defaultValues: { carrierMethod, carrier, method },
58
- })
59
-
60
- const { handleSubmit, control, setValue, register, required, error } = form
61
- const submit = handleSubmit(() => {})
62
- useFormCompose({ form, step, submit, key: 'ShippingMethodForm' })
63
-
64
- const classes = withState({ itemCount: sortedAvailableShippingMethods.length })
65
- return (
66
- <Form onSubmit={submit} noValidate>
67
- <input type='hidden' {...register('carrier', { required: required.carrier })} />
68
- <input type='hidden' {...register('method', { required: required.method })} />
69
-
70
- <FormRow
71
- className={classes.root}
72
- sx={(theme) => ({
73
- marginTop: theme.spacings.xs,
74
- position: 'relative',
75
- padding: 0,
76
- })}
77
- >
78
- <ScrollerProvider scrollSnapAlign='center'>
79
- <Box
80
- className={classes.buttonContainer}
81
- sx={{
82
- position: 'absolute',
83
- left: 0,
84
- zIndex: 2,
85
- height: '100%',
86
- '& > div': { height: '100%' },
87
- }}
88
- >
89
- <ScrollerButton
90
- direction='left'
91
- className={classes.buttonRoot}
92
- sx={{
93
- bgcolor: 'background.default',
94
- borderRadius: 0,
95
- width: '30px',
96
- height: '100%',
97
- boxShadow: 'none',
98
- borderWidth: 1,
99
- borderColor: 'divider',
100
- '&:focus': {
101
- boxShadow: 'none',
102
- },
103
- borderTopLeftRadius: 4,
104
- borderBottomLeftRadius: 4,
105
- '&.itemCount1, &.itemCount2': {
106
- display: 'none',
107
- },
108
- }}
109
- >
110
- <IconSvg
111
- src={iconChevronLeft}
112
- size='small'
113
- aria-label={i18n._(/* i18n */ `Scroll Left`)}
114
- />
115
- </ScrollerButton>
116
- </Box>
117
-
118
- <FormControl>
119
- <Controller
120
- defaultValue={carrierMethod}
121
- control={control}
122
- name='carrierMethod'
123
- rules={{ required: 'Please select a shipping method' }}
124
- render={({ field: { onChange, value, onBlur }, fieldState: { invalid } }) => (
125
- <>
126
- <Scroller
127
- className={classes.scrollerRoot}
128
- sx={[
129
- {
130
- gridTemplateRows: `100%`,
131
- gridTemplateColumns: `repeat(2, calc(50% - 20px))`,
132
- gap: `6px`,
133
- borderRadius: 0,
134
- padding: '1px 1px',
135
- '&:focus': {
136
- outline: 'unset',
137
- },
138
- },
139
- sortedAvailableShippingMethods.length === 2 && {
140
- gridTemplateColumns: `repeat(2, calc(50% - 4px))`,
141
- },
142
- sortedAvailableShippingMethods.length === 1 && {
143
- gridTemplateColumns: `repeat(2, calc(100% - 8px))`,
144
- },
145
- ]}
146
- hideScrollbar
147
- tabIndex={0}
148
- >
149
- {sortedAvailableShippingMethods.map((shippingMethod) => {
150
- if (!shippingMethod) return null
151
- const code = `${shippingMethod?.carrier_code}-${shippingMethod?.method_code}`
152
- return (
153
- <AvailableShippingMethod
154
- key={code}
155
- value={code}
156
- onChange={(_, val: string) => {
157
- onChange(val)
158
- setValue('carrier', val.split('-')?.[0])
159
- setValue('method', val.split('-')?.[1])
160
-
161
- // todo(paales): what if there are additional options to submit, shouldn't we wait for that or will those always come back from this mutation?
162
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
163
- submit()
164
- }}
165
- onBlur={onBlur}
166
- selected={value === code}
167
- {...shippingMethod}
168
- >
169
- Delivery from: Mon - Sat
170
- </AvailableShippingMethod>
171
- )
172
- })}
173
- {!currentAddress?.available_shipping_methods && (
174
- <AvailableShippingMethod
175
- available={false}
176
- carrier_code='none'
177
- carrier_title={i18n._(/* i18n */ `No shipping methods available`)}
178
- >
179
- <Trans id='Please fill in your address to see shipping methods' />
180
- </AvailableShippingMethod>
181
- )}
182
- </Scroller>
183
-
184
- {invalid && currentAddress?.available_shipping_methods && (
185
- <Alert
186
- className={classes.alert}
187
- severity='error'
188
- sx={(theme) => ({
189
- marginTop: theme.spacings.xxs,
190
- })}
191
- >
192
- Please select a shipping method
193
- </Alert>
194
- )}
195
- </>
196
- )}
197
- />
198
- </FormControl>
199
-
200
- <Box
201
- sx={{
202
- position: 'absolute',
203
- right: 0,
204
- zIndex: 2,
205
- height: '100%',
206
- '& > div': { height: '100%' },
207
- }}
208
- className={classes.buttonContainer}
209
- >
210
- <ScrollerButton
211
- direction='right'
212
- sx={{
213
- bgcolor: 'background.default',
214
- borderRadius: 0,
215
- width: '30px',
216
- height: '100%',
217
- boxShadow: 'none',
218
- borderWidth: 1,
219
- borderColor: 'divider',
220
- '&:focus': {
221
- boxShadow: 'none',
222
- },
223
- borderTopRightRadius: 4,
224
- borderBottomRightRadius: 4,
225
- '&.itemCount1, &.itemCount2': {
226
- display: 'none',
227
- },
228
- }}
229
- className={classes.buttonRoot}
230
- >
231
- <IconSvg
232
- src={iconChevronRight}
233
- size='small'
234
- aria-label={i18n._(/* i18n */ `Scroll Right`)}
235
- />
236
- </ScrollerButton>
237
- </Box>
238
- </ScrollerProvider>
239
- </FormRow>
240
-
241
- <ApolloCartErrorAlert error={error} />
242
- </Form>
243
- )
244
- }