@graphcommerce/docs 6.0.0-canary.45 → 6.0.0-canary.47

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,9 @@
1
1
  # Change Log
2
2
 
3
+ ## 6.0.0-canary.47
4
+
5
+ ## 6.0.0-canary.46
6
+
3
7
  ## 6.0.0-canary.45
4
8
 
5
9
  ## 6.0.0-canary.44
package/feature-list.md CHANGED
@@ -39,7 +39,7 @@ Features taken from the Magento Commerce 2 Feature List
39
39
  store data. — [Commerce]
40
40
  - [x] Offer free shipping and percent, fixed amount, and buy X get Y free
41
41
  discounts. — [Commerce]
42
- - [ ] Set multi-tier pricing for quantity discounts. — [Todo]
42
+ - [x] Set multi-tier pricing for quantity discounts.
43
43
  - [ ] Get minimum advertised price (MAP) support. — [Todo]
44
44
 
45
45
  ### Search engine optimization
@@ -1,160 +1,121 @@
1
1
  # Plugins React
2
2
 
3
- GraphCommerce's React plugin system allows you to extend GraphCommerce in a
4
- plug-and-play manner. Install a new package and the code will be added at the
5
- right places.
3
+ GraphCommerce's React plugin system allows you to extend GraphCommerce's build
4
+ in components with your own logic.
6
5
 
7
- - Plug-and-play: It is be possible to install packages after which they
8
- immediately work.
9
6
  - No runtime overhead: The plugin system is fully implemented in webpack and
10
7
  - Easy plugin creation: Configuration should happen in the plugin file, not a
11
8
  separate configuration file.
9
+ - Should be validated with TypeScript
12
10
 
13
- ## What problem are we solving?
14
-
15
- Without plugins the only way to add new functionality is by modifying the code
16
- of your project at multiple places. We often pass props to components to
17
- customize them, but sometimes we also place hooks at multiple places.
18
-
19
- For example, to add a new payment method it was necessary to modify the props of
20
- `<PaymentMethodContextProvider methods={[...braintree]}>`
21
-
22
- This causes problems:
23
-
24
- - Upgrades: If GraphCommerce changes something somewhere in the code where you
25
- have already modified the code, you get an upgrade conflict which you have to
26
- manually resolve. By using plugins you can avoid this.
27
- - New packages: When you install a complex new package, it can happen that you
28
- have to modify the code of your project at multiple places. This is not
29
- necessary with plugins.
30
-
31
- ## What is a plugin?
11
+ ## What is a plugin
32
12
 
33
13
  A plugin is a way to modify React Components by wrapping them, without having to
34
- modify the code in `examples/magento-graphcms` or `your-project`.
14
+ modify the code directly.
35
15
 
36
16
  For the M2 people: Think of around plugins, but without configuration files and
37
17
  no performance penalty.
38
18
 
39
- In the [PR](https://github.com/graphcommerce-org/graphcommerce/pull/1718) I have
40
- made the
41
- [`<PaymentMethodContextProvider />`](https://github.com/graphcommerce-org/graphcommerce/pull/1718/files#diff-d5b4da6c34d4b40dc8ac5d1c5967bc6f5aaa70d0d5ac79552f3a980b17a88ea9R115)
42
- work with plugins.
43
-
44
- The actual plugins are:
45
-
46
- - [AddBraintreeMethods](https://github.com/graphcommerce-org/graphcommerce/pull/1718/files#diff-14391e8c8f598e720b3e99ece1248987d68eb6133d354a3a55ef82331905be5b)
47
- - [AddIncludedMethods](https://github.com/graphcommerce-org/graphcommerce/pull/1718/files#diff-c3d57b802463ed40925b558049a56992202be975f3c86982e6a753e2830bdb9f)
48
- - [AddPaypalMethods](https://github.com/graphcommerce-org/graphcommerce/pull/1718/files#diff-934d7a9d597b01b6da875f61ca1cdfd57e0e0817e7126ce6216fd82dc4b6f899)
49
- - [AddMollieMethods](https://github.com/graphcommerce-org/graphcommerce/pull/1718/files#diff-76e6fc63dee67f55cbad4f13dc7b1b764da6235b88ed8d987c7044b7ef7fc942)
50
-
51
- The result of this is that:
52
-
53
- - The payment methods are added to the `<PaymentMethodContextProvider />` via
54
- plugins.
55
- - These plugins are only applied if the relevant package is installed.
56
-
57
- ### How do I make a plugin?
58
-
59
- In the root of my project, i've created a plugin
60
- `examples/magento-graphcms/plugins/AddPaymentMethodEnhancer.tsx` that adds
61
- purchaseorder to `<PaymentMethodContextProvider/>`
19
+ ## How do I write a plugin?
20
+
21
+ In this example we're going to add a 'BY GC' text to list items, as can seen on
22
+ the demo on
23
+ [category pages](https://graphcommerce.vercel.app/nl/women/business).
24
+
25
+ 1. Create a new file in `/plugins/ProductListItemByGC.tsx` with the following
26
+ contents:
27
+
28
+ ```tsx
29
+ import type { ProductListItemProps } from '@graphcommerce/magento-product'
30
+ import type { PluginProps } from '@graphcommerce/next-config'
31
+ import { Typography } from '@mui/material'
32
+
33
+ export const component = 'ProductListItem' // Component to extend, required
34
+ export const exported = '@graphcommerce/magento-product' // Location where the component is exported, required
35
+
36
+ function AwesomeProductListItem(props: PluginProps<ProductListItemProps>) {
37
+ // Prev in this case is ProductListItem, you should be able to see this if you log it.
38
+ const { Prev, ...rest } = props
39
+ return (
40
+ <Prev
41
+ {...rest}
42
+ subTitle={
43
+ <Typography component='span' variant='caption'>
44
+ Plugin!
45
+ </Typography>
46
+ }
47
+ />
48
+ )
49
+ }
50
+ export const Plugin = AwesomeProductListItem // An export with the name Plugin, required
51
+ ```
52
+
53
+ 2. Trigger the 'interceptor generation' so GraphCommerce knows of the existence
54
+ of your plugin. To enable: Modify the page that you expect the plugin to
55
+ occur on. In this case modify `pages/[...url].tsx` by adding a few linebreaks
56
+ and save the file
57
+
58
+ If everything went as expected you should see `Plugin!` below the product
59
+ name.
60
+
61
+ 3. Happy programming!
62
+
63
+ ## How does it work?
64
+
65
+ After the creation of the plugin file GraphCommerce will create an interceptor
66
+ file to load you plugin. To see what has happened, open the
67
+ `node_modules/@graphcommerce/magento-product/index.interceptor.tsx` and you
68
+ should see something like:
62
69
 
63
70
  ```tsx
64
- import type { PaymentMethodContextProviderProps } from '@graphcommerce/magento-cart-payment-method'
65
- import type { PluginProps } from '@graphcommerce/next-config'
66
- import { purchaseorder } from '../PurchaseOrder'
67
-
68
- // Component to extend, required
69
- export const component = 'PaymentMethodContextProvider'
71
+ export * from '.'
72
+ import { Plugin as AwesomeProductListItem } from '../../examples/magento-graphcms/plugins/AwesomeProductListItem'
73
+ import { ComponentProps } from 'react'
74
+ import { ProductListItem as ProductListItemBase } from '.'
70
75
 
71
- // Exported location of the component that you are extending, required
72
- export const exported = '@graphcommerce/magento-cart-payment-method'
76
+ /**
77
+ * Interceptor for `<ProductListItem/>` with these plugins:
78
+ *
79
+ * - `../../examples/magento-graphcms/plugins/AwesomeProductListItem`
80
+ */
81
+ type ProductListItemProps = ComponentProps<typeof ProductListItemBase>
73
82
 
74
- function AddPaymentMethodEnhancer(
75
- props: PluginProps<PaymentMethodContextProviderProps>,
76
- ) {
77
- const { Prev, modules, ...rest } = props
78
- return <Prev {...rest} modules={{ ...modules, purchaseorder }} />
83
+ function AwesomeProductListItemInterceptor(props: ProductListItemProps) {
84
+ return <AwesomeProductListItem {...props} Prev={ProductListItemBase} />
79
85
  }
80
-
81
- /** The export must be named `Plugin` and must accept a Prev component to render */
82
- export const Plugin = AddIncludedMethods
86
+ export const ProductListItem = AwesomeProductListItemInterceptor
83
87
  ```
84
88
 
85
- ### How does it work?
89
+ If you read the interceptor file from the bottom up, you see:
86
90
 
87
- 1. It generates a list of all packages with `graphcommerce` in the package
88
- `name` (All `@graphcommerce/*` packages and
89
- `@my-company/graphcommerce-plugin-name`).
90
- 2. It does a glob search for plugins in the plugins folders for each package:
91
- `${packageLocation}/plugins/**/*.tsx`.
92
- 3. Statically Analyse the plugins, check if the `component` and `exported`
93
- exports exist and generate the plugin configuration.
94
- 4. Generate `PaymentMethodContext.interceptor.tsx` and place it next to the
95
- existing component
91
+ - The original `ProductListItem` is replaced with
92
+ `AwesomeProductListItemInterceptor`
93
+ - `AwesomeProductListItemInterceptor` is a react component which renders
94
+ `AwesomeProductListItem` with a `Prev` prop.
95
+ - `AwesomeProductListItem` is the plugin you just created.
96
+ - `Prev` is the original `ProductListItem` (renamed to `ProductListItemBase`)
97
+ - `ProductListItemProps` are the props of the original `ProductListItem` and
98
+ thus your plugin is automatically validated by TypeScript.
96
99
 
97
- Example of generated interceptor with additional comments:
100
+ So in conclusion, a plugin is a react component that renders the original
101
+ component with a `Prev` prop. The `Prev` prop is the original component.
98
102
 
99
- ```tsx
100
- /* This file is automatically generated for @graphcommerce/magento-cart-payment-method */
103
+ When opening the React debugger you can see the plugin wrapped.
101
104
 
102
- export * from '.'
103
- import { Plugin as GaPaymentMethodButton } from '@graphcommerce/googleanalytics/plugins/GaPaymentMethodButton'
104
- import { Plugin as GaPaymentMethodContextProvider } from '@graphcommerce/googleanalytics/plugins/GaPaymentMethodContextProvider'
105
- import { Plugin as AddIncludedMethods } from '@graphcommerce/magento-payment-included/plugins/AddIncludedMethods'
106
- import { ComponentProps } from 'react'
107
- import {
108
- PaymentMethodButton as PaymentMethodButtonBase,
109
- PaymentMethodContextProvider as PaymentMethodContextProviderBase,
110
- } from '.'
105
+ <img width="263" alt="Scherm­afbeelding 2023-03-15 om 12 16 59" src="https://user-images.githubusercontent.com/1244416/225293707-1ce1cd87-108b-4f28-b9ee-0c5d68d9a886.png">
111
106
 
112
- /**
113
- * Interceptor for `<PaymentMethodButton/>` with these plugins:
114
- *
115
- * - `@graphcommerce/googleanalytics/plugins/GaPaymentMethodButton`
116
- */
117
- type PaymentMethodButtonProps = ComponentProps<typeof PaymentMethodButtonBase>
107
+ ### How are plugins loaded?
118
108
 
119
- function GaPaymentMethodButtonInterceptor(props: PaymentMethodButtonProps) {
120
- return <GaPaymentMethodButton {...props} Prev={PaymentMethodButtonBase} />
121
- }
122
- export const PaymentMethodButton = GaPaymentMethodButtonInterceptor
109
+ GraphCommerce uses a custom Webpack plugin to load the plugins. The plugin does
110
+ a glob search for plugin folders in each GraphCommerce related pacakge:
111
+ `${packageLocation}/plugins/**/*.tsx`
123
112
 
124
- /**
125
- * Interceptor for `<PaymentMethodContextProvider/>` with these plugins:
126
- *
127
- * - `@graphcommerce/magento-payment-included/plugins/AddIncludedMethods`
128
- * - `@graphcommerce/googleanalytics/plugins/GaPaymentMethodContextProvider`
129
- */
130
- type PaymentMethodContextProviderProps = ComponentProps<
131
- typeof PaymentMethodContextProviderBase
132
- >
133
-
134
- function AddIncludedMethodsInterceptor(
135
- props: PaymentMethodContextProviderProps,
136
- ) {
137
- return (
138
- <AddIncludedMethods {...props} Prev={PaymentMethodContextProviderBase} />
139
- )
140
- }
141
- function GaPaymentMethodContextProviderInterceptor(
142
- props: PaymentMethodContextProviderProps,
143
- ) {
144
- return (
145
- <GaPaymentMethodContextProvider
146
- {...props}
147
- Prev={AddIncludedMethodsInterceptor}
148
- />
149
- )
150
- }
151
- export const PaymentMethodContextProvider =
152
- GaPaymentMethodContextProviderInterceptor
153
- ```
154
-
155
- React profile will show that all components are nested:
113
+ Package locations are the root and all packages with `graphcommerce` in the name
114
+ (This means all `@graphcommerce/*` packages and
115
+ `@your-company/graphcommerce-plugin-name`)
156
116
 
157
- ![](https://user-images.githubusercontent.com/1244416/197813853-e8aa329e-41bc-4f56-8aac-2464cc37032f.png)
117
+ The Webpack plugin statically analyses the plugin file to find `component`,
118
+ `exported` and `ifConfig` and extracts that information.
158
119
 
159
120
  ### Possible use cases
160
121
 
@@ -172,17 +133,13 @@ work for other things such as:
172
133
  ### Conditionally include a plugin
173
134
 
174
135
  Provide an ifConfig export in the plugin that will only include the plugin if a
175
- configuration value is truety.
136
+ [configuration](./config.md) value is truety.
176
137
 
177
138
  ```tsx
178
- export const ifConfig = 'googleAnalytics'
139
+ import type { IfConfig } from '@graphcommerce/next-config'
140
+ export const ifConfig: IfConfig = 'googleAnalytics'
179
141
  ```
180
142
 
181
- ### When to use a plugin?
182
-
183
- A plugin should be used when a new package is created that influences the
184
- behavior of other packages.
185
-
186
143
  ### Plugin loading order
187
144
 
188
145
  A plugin is injected later than the dependencies of the package. So if a plugin
package/package.json CHANGED
@@ -2,10 +2,10 @@
2
2
  "name": "@graphcommerce/docs",
3
3
  "homepage": "https://www.graphcommerce.org/docs",
4
4
  "repository": "github:graphcommerce-org/graphcommerce/docs",
5
- "version": "6.0.0-canary.45",
5
+ "version": "6.0.0-canary.47",
6
6
  "sideEffects": true,
7
7
  "devDependencies": {
8
- "@graphcommerce/prettier-config-pwa": "6.0.0-canary.45"
8
+ "@graphcommerce/prettier-config-pwa": "6.0.0-canary.47"
9
9
  },
10
10
  "prettier": "@graphcommerce/prettier-config-pwa"
11
11
  }