From 6e85858673453403449300c34f9bc59b0a9c48f2 Mon Sep 17 00:00:00 2001 From: Paul Hachmang Date: Tue, 30 Apr 2024 11:30:13 +0200 Subject: [PATCH 1/3] Make sure a single plugin can can override multiple exports at once. --- .../next-config/src/interceptors/generateInterceptor.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packagesDev/next-config/src/interceptors/generateInterceptor.ts b/packagesDev/next-config/src/interceptors/generateInterceptor.ts index 8c8b8779a8..70414da1be 100644 --- a/packagesDev/next-config/src/interceptors/generateInterceptor.ts +++ b/packagesDev/next-config/src/interceptors/generateInterceptor.ts @@ -74,7 +74,7 @@ const sourceSuffix = 'Plugin' const interceptorSuffix = 'Interceptor' const disabledSuffix = 'Disabled' const name = (plugin: PluginConfig) => - `${plugin.sourceModule + `${plugin.sourceExport}${plugin.sourceModule .split('/') [plugin.sourceModule.split('/').length - 1].replace(/[^a-zA-Z0-9]/g, '')}` @@ -180,9 +180,7 @@ export async function generateInterceptor( s.replace(originalSuffix, disabledSuffix), ).visitModule(ast) - carryProps.push(interceptorPropsName(name(p))) - - result = `type ${interceptorPropsName(name(p))} = React.ComponentProps` + carryProps.push(`React.ComponentProps`) pluginSee.push( `@see {${sourceName(name(p))}} for replacement of the original source (original source not used)`, From c0fde99c35a6f85047033cdbfa1febcd613c3c77 Mon Sep 17 00:00:00 2001 From: Paul Hachmang Date: Tue, 30 Apr 2024 13:36:25 +0200 Subject: [PATCH 2/3] =?UTF-8?q?Support=20`export=20{=20default=20as=20XXX}?= =?UTF-8?q?=20from=20=E2=80=98YYY=E2=80=99`=20pattern=20when=20writing=20p?= =?UTF-8?q?lugins.=20Fix=20multiple=20exports=20per=20plugin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interceptors/generateInterceptors.ts | 177 ++++++++++++------ .../dist/interceptors/findOriginalSource.js | 18 +- .../dist/interceptors/generateInterceptor.js | 7 +- .../src/interceptors/findOriginalSource.ts | 17 +- .../src/interceptors/generateInterceptor.ts | 2 +- 5 files changed, 160 insertions(+), 61 deletions(-) diff --git a/packagesDev/next-config/__tests__/interceptors/generateInterceptors.ts b/packagesDev/next-config/__tests__/interceptors/generateInterceptors.ts index ffd281b076..6f332c6448 100644 --- a/packagesDev/next-config/__tests__/interceptors/generateInterceptors.ts +++ b/packagesDev/next-config/__tests__/interceptors/generateInterceptors.ts @@ -74,17 +74,20 @@ it('it generates an interceptor', async () => { interceptors['packages/magento-cart-payment-method/PaymentMethodContext/PaymentMethodContext'] ?.template expectInterceptor(result).toMatchInlineSnapshot(` - "type AddBraintreeMethodsProps = OmitPrev, 'Prev'> + "type PluginAddBraintreeMethodsProps = OmitPrev< + React.ComponentProps, + 'Prev' + > - const AddBraintreeMethodsInterceptor = (props: AddBraintreeMethodsProps) => ( - + const PluginAddBraintreeMethodsInterceptor = (props: PluginAddBraintreeMethodsProps) => ( + ) - type AddMollieMethodsProps = AddBraintreeMethodsProps & - OmitPrev, 'Prev'> + type PluginAddMollieMethodsProps = PluginAddBraintreeMethodsProps & + OmitPrev, 'Prev'> - const AddMollieMethodsInterceptor = (props: AddMollieMethodsProps) => ( - + const PluginAddMollieMethodsInterceptor = (props: PluginAddMollieMethodsProps) => ( + ) /** @@ -93,10 +96,10 @@ it('it generates an interceptor', async () => { * This file is NOT meant to be modified directly and is auto-generated if the plugins or the original source changes. * * @see {@link file://./PaymentMethodContext.tsx} for original source file - * @see {AddBraintreeMethods} for source of applied plugin - * @see {AddMollieMethods} for source of applied plugin + * @see {PluginAddBraintreeMethods} for source of applied plugin + * @see {PluginAddMollieMethods} for source of applied plugin */ - export const PaymentMethodContextProvider = AddMollieMethodsInterceptor" + export const PaymentMethodContextProvider = PluginAddMollieMethodsInterceptor" `) }) @@ -124,7 +127,7 @@ it("resolves a 'root plugin' to be relative to the interceptor", async () => { ).toMatchInlineSnapshot(` "import type { DistributedOmit as OmitPrev } from 'type-fest' - import { Plugin as AddPaymentMethodEnhancer } from '../../../plugins/AddPaymentMethodEnhancer'" + import { Plugin as PluginAddPaymentMethodEnhancer } from '../../../plugins/AddPaymentMethodEnhancer'" `) }) @@ -157,24 +160,27 @@ it('it can apply multiple plugins to a single export', async () => { expectImport(result).toMatchInlineSnapshot(` "import type { DistributedOmit as OmitPrev } from 'type-fest' - import { Plugin as AddAdyenMethods } from '@graphcommerce/magento-payment-adyen/plugins/AddAdyenMethods' - import { Plugin as AddMollieMethods } from '@graphcommerce/mollie-magento-payment/plugins/AddMollieMethods'" + import { Plugin as PluginAddAdyenMethods } from '@graphcommerce/magento-payment-adyen/plugins/AddAdyenMethods' + import { Plugin as PluginAddMollieMethods } from '@graphcommerce/mollie-magento-payment/plugins/AddMollieMethods'" `) expectOriginal(result).toContain('PaymentMethodContextProviderOriginal') expectInterceptor(result).toMatchInlineSnapshot(` - "type AddAdyenMethodsProps = OmitPrev, 'Prev'> + "type PluginAddAdyenMethodsProps = OmitPrev< + React.ComponentProps, + 'Prev' + > - const AddAdyenMethodsInterceptor = (props: AddAdyenMethodsProps) => ( - + const PluginAddAdyenMethodsInterceptor = (props: PluginAddAdyenMethodsProps) => ( + ) - type AddMollieMethodsProps = AddAdyenMethodsProps & - OmitPrev, 'Prev'> + type PluginAddMollieMethodsProps = PluginAddAdyenMethodsProps & + OmitPrev, 'Prev'> - const AddMollieMethodsInterceptor = (props: AddMollieMethodsProps) => ( - + const PluginAddMollieMethodsInterceptor = (props: PluginAddMollieMethodsProps) => ( + ) /** @@ -183,10 +189,10 @@ it('it can apply multiple plugins to a single export', async () => { * This file is NOT meant to be modified directly and is auto-generated if the plugins or the original source changes. * * @see {@link file://./PaymentMethodContext.tsx} for original source file - * @see {AddAdyenMethods} for source of applied plugin - * @see {AddMollieMethods} for source of applied plugin + * @see {PluginAddAdyenMethods} for source of applied plugin + * @see {PluginAddMollieMethods} for source of applied plugin */ - export const PaymentMethodContextProvider = AddMollieMethodsInterceptor" + export const PaymentMethodContextProvider = PluginAddMollieMethodsInterceptor" `) }) @@ -218,10 +224,13 @@ it('it handles on duplicates gracefully', async () => { interceptors['packages/magento-cart-payment-method/PaymentMethodContext/PaymentMethodContext'] ?.template expectInterceptor(result).toMatchInlineSnapshot(` - "type AddBraintreeMethodsProps = OmitPrev, 'Prev'> + "type PluginAddBraintreeMethodsProps = OmitPrev< + React.ComponentProps, + 'Prev' + > - const AddBraintreeMethodsInterceptor = (props: AddBraintreeMethodsProps) => ( - + const PluginAddBraintreeMethodsInterceptor = (props: PluginAddBraintreeMethodsProps) => ( + ) /** @@ -230,9 +239,9 @@ it('it handles on duplicates gracefully', async () => { * This file is NOT meant to be modified directly and is auto-generated if the plugins or the original source changes. * * @see {@link file://./PaymentMethodContext.tsx} for original source file - * @see {AddBraintreeMethods} for source of applied plugin + * @see {PluginAddBraintreeMethods} for source of applied plugin */ - export const PaymentMethodContextProvider = AddBraintreeMethodsInterceptor" + export const PaymentMethodContextProvider = PluginAddBraintreeMethodsInterceptor" `) }) @@ -389,8 +398,8 @@ it('adds debug logging to interceptors for components', async () => { ) expectImport(interceptors['packages/graphql/config']?.template).toMatchInlineSnapshot(` - "import { plugin as magentoInitMemoryCache } from '@graphcommerce/magento-graphql/plugins/magentoInitMemoryCache' - import { plugin as hygraphInitMemoryCache } from '@graphcommerce/magento-hygraph/plugins/hygraphInitMemoryCache'" + "import { plugin as pluginmagentoInitMemoryCache } from '@graphcommerce/magento-graphql/plugins/magentoInitMemoryCache' + import { plugin as pluginhygraphInitMemoryCache } from '@graphcommerce/magento-hygraph/plugins/hygraphInitMemoryCache'" `) expectOriginal(interceptors['packages/graphql/config']?.template).toMatchInlineSnapshot(` @@ -423,17 +432,19 @@ it('adds debug logging to interceptors for components', async () => { console.warn(log, ...additional) } - const hygraphInitMemoryCacheInterceptor: typeof graphqlConfigOriginal = (...args) => { + const pluginhygraphInitMemoryCacheInterceptor: typeof graphqlConfigOriginal = (...args) => { logOnce( - \`🔌 Calling graphqlConfig with plugin(s): magentoInitMemoryCache wrapping hygraphInitMemoryCache wrapping graphqlConfig()\`, + \`🔌 Calling graphqlConfig with plugin(s): pluginmagentoInitMemoryCache wrapping pluginhygraphInitMemoryCache wrapping graphqlConfig()\`, ) - return hygraphInitMemoryCache(graphqlConfigOriginal, ...args) + return pluginhygraphInitMemoryCache(graphqlConfigOriginal, ...args) } - const magentoInitMemoryCacheInterceptor: typeof hygraphInitMemoryCacheInterceptor = (...args) => { + const pluginmagentoInitMemoryCacheInterceptor: typeof pluginhygraphInitMemoryCacheInterceptor = ( + ...args + ) => { logOnce( - \`🔌 Calling graphqlConfig with plugin(s): hygraphInitMemoryCache wrapping magentoInitMemoryCache wrapping graphqlConfig()\`, + \`🔌 Calling graphqlConfig with plugin(s): pluginhygraphInitMemoryCache wrapping pluginmagentoInitMemoryCache wrapping graphqlConfig()\`, ) - return magentoInitMemoryCache(hygraphInitMemoryCacheInterceptor, ...args) + return pluginmagentoInitMemoryCache(pluginhygraphInitMemoryCacheInterceptor, ...args) } /** @@ -442,10 +453,10 @@ it('adds debug logging to interceptors for components', async () => { * This file is NOT meant to be modified directly and is auto-generated if the plugins or the original source changes. * * @see {@link file://./config.ts} for original source file - * @see {hygraphInitMemoryCache} for source of applied plugin - * @see {magentoInitMemoryCache} for source of applied plugin + * @see {pluginhygraphInitMemoryCache} for source of applied plugin + * @see {pluginmagentoInitMemoryCache} for source of applied plugin */ - export const graphqlConfig = magentoInitMemoryCacheInterceptor" + export const graphqlConfig = pluginmagentoInitMemoryCacheInterceptor" `) }) @@ -515,14 +526,12 @@ it('Should apply overrides to the correct file', async () => { interceptors['packages/magento-product/components/ProductStaticPaths/getProductStaticPaths'] ?.template expectImport(result).toMatchInlineSnapshot( - `"import { getProductStaticPaths as replaceGetProductStaticPaths } from '../../../../plugins/replaceGetProductStaticPaths'"`, + `"import { getProductStaticPaths as getProductStaticPathsreplaceGetProductStaticPaths } from '../../../../plugins/replaceGetProductStaticPaths'"`, ) expectOriginal(result).toContain(`getProductStaticPathsDisabled`) }) -it('Should report an error when multiple files are overriding the same export', () => {}) - it('correctly reports an error for an incorrect export', async () => { const fakeconfig = { googleRecaptchaKey: '123', @@ -644,8 +653,8 @@ export const Plugin = ConfigurableProductPageName expectImport(result).toMatchInlineSnapshot(` "import type { DistributedOmit as OmitPrev } from 'type-fest' - import { Plugin as ConfigurableProductPageName } from '@graphcommerce/magento-product-configurable/plugins/ConfigurableProductPage/ConfigurableProductPageName' - import { ProductPageName as MyPlugin } from '../../../../plugins/MyPlugin'" + import { Plugin as PluginConfigurableProductPageName } from '@graphcommerce/magento-product-configurable/plugins/ConfigurableProductPage/ConfigurableProductPageName' + import { ProductPageName as ProductPageNameMyPlugin } from '../../../../plugins/MyPlugin'" `) expectOriginal(result).toMatchInlineSnapshot(` @@ -660,14 +669,12 @@ export const Plugin = ConfigurableProductPageName `) expectInterceptor(result).toMatchInlineSnapshot(` - "type MyPluginProps = React.ComponentProps - - type ConfigurableProductPageNameProps = MyPluginProps & - OmitPrev, 'Prev'> + "type PluginConfigurableProductPageNameProps = React.ComponentProps & + OmitPrev, 'Prev'> - const ConfigurableProductPageNameInterceptor = (props: ConfigurableProductPageNameProps) => ( - - ) + const PluginConfigurableProductPageNameInterceptor = ( + props: PluginConfigurableProductPageNameProps, + ) => /** * Here you see the 'interceptor' that is applying all the configured plugins. @@ -675,10 +682,10 @@ export const Plugin = ConfigurableProductPageName * This file is NOT meant to be modified directly and is auto-generated if the plugins or the original source changes. * * @see {@link file://./ProductPageName.tsx} for original source file - * @see {MyPlugin} for replacement of the original source (original source not used) - * @see {ConfigurableProductPageName} for source of applied plugin + * @see {ProductPageNameMyPlugin} for replacement of the original source (original source not used) + * @see {PluginConfigurableProductPageName} for source of applied plugin */ - export const ProductPageName = ConfigurableProductPageNameInterceptor" + export const ProductPageName = PluginConfigurableProductPageNameInterceptor" `) }) @@ -702,3 +709,65 @@ it('generates to a .ts file when the target file is a .ts as well', async () => const interceptor = interceptors['packages/graphql/config'] expect(interceptor.sourcePath).toBe(`packages/graphql/config.ts`) }) + +it.todo('Should report an error when multiple files are overriding the same export') + +it('Can correctly find exports that are default exports', async () => { + const pluginSource = ` + import { PluginConfig } from '@graphcommerce/next-config' + + import accessibilityHuman from '@graphcommerce/next-ui/icons/accessibility-human.svg' + import alarm from '@graphcommerce/next-ui/icons/alarm.svg' + + export const config: PluginConfig = { + type: 'replace', + module: '@graphcommerce/next-ui', + } + + export const iconChevronLeft = accessibilityHuman + export const iconChevronRight = alarm + ` + + const config = { + demoMode: true, + configurableVariantForSimple: true, + configurableVariantValues: { content: true, gallery: true, url: true }, + } as GraphCommerceConfig + + const plugins = parseStructure(parseSync(pluginSource), config, './plugins/MyProjectIcon') + + const interceptors = await generateInterceptors(plugins, resolveDependency(projectRoot)) + expect(Object.keys(interceptors)[0]).toMatchInlineSnapshot(`"packages/next-ui/icons"`) + + const result = interceptors['packages/next-ui/icons']?.template + + expectImport(result).toMatchInlineSnapshot(` + "import { iconChevronLeft as iconChevronLeftMyProjectIcon } from '../../plugins/MyProjectIcon' + import { iconChevronRight as iconChevronRightMyProjectIcon } from '../../plugins/MyProjectIcon'" + `) + + expectOriginal(result).toContain('iconChevronLeftDisabled') + expectOriginal(result).toContain('iconChevronRightDisabled') + + expectInterceptor(result).toMatchInlineSnapshot(` + "/** + * Here you see the 'interceptor' that is applying all the configured plugins. + * + * This file is NOT meant to be modified directly and is auto-generated if the plugins or the original source changes. + * + * @see {@link file://./icons.ts} for original source file + * @see {iconChevronLeftMyProjectIcon} for replacement of the original source (original source not used) + */ + export const iconChevronLeft = iconChevronLeftMyProjectIcon + + /** + * Here you see the 'interceptor' that is applying all the configured plugins. + * + * This file is NOT meant to be modified directly and is auto-generated if the plugins or the original source changes. + * + * @see {@link file://./icons.ts} for original source file + * @see {iconChevronRightMyProjectIcon} for replacement of the original source (original source not used) + */ + export const iconChevronRight = iconChevronRightMyProjectIcon" + `) +}) diff --git a/packagesDev/next-config/dist/interceptors/findOriginalSource.js b/packagesDev/next-config/dist/interceptors/findOriginalSource.js index 664a56334b..467a40f69b 100644 --- a/packagesDev/next-config/dist/interceptors/findOriginalSource.js +++ b/packagesDev/next-config/dist/interceptors/findOriginalSource.js @@ -33,6 +33,22 @@ function parseAndFindExport(resolved, findExport, resolve) { break; } } + if (node.type === 'ExportNamedDeclaration') { + for (const specifier of node.specifiers) { + if (specifier.type === 'ExportSpecifier') { + if (specifier.exported?.value === findExport) + return resolved; + } + else if (specifier.type === 'ExportDefaultSpecifier') { + // todo + } + else if (specifier.type === 'ExportNamespaceSpecifier') { + // todo + } + } + } + // todo: if (node.type === 'ExportDefaultDeclaration') {} + // todo: if (node.type === 'ExportDefaultExpression') {} } const exports = ast.body .filter((node) => node.type === 'ExportAllDeclaration') @@ -78,7 +94,7 @@ function findOriginalSource(plug, resolved, resolve) { if (!newResolved) { return { resolved: undefined, - error: new Error(`Can not find ${plug.targetModule}#${plug.sourceExport} for plugin ${plug.sourceModule}`), + error: new Error(`Plugin target not found ${plug.targetModule}#${plug.sourceExport} for plugin ${plug.sourceModule}#${plug.sourceExport}`), }; } // cachedResults.set(cacheKey, newResolved) diff --git a/packagesDev/next-config/dist/interceptors/generateInterceptor.js b/packagesDev/next-config/dist/interceptors/generateInterceptor.js index 11dbe3bdec..f55139f274 100644 --- a/packagesDev/next-config/dist/interceptors/generateInterceptor.js +++ b/packagesDev/next-config/dist/interceptors/generateInterceptor.js @@ -45,7 +45,7 @@ const originalSuffix = 'Original'; const sourceSuffix = 'Plugin'; const interceptorSuffix = 'Interceptor'; const disabledSuffix = 'Disabled'; -const name = (plugin) => `${plugin.sourceModule +const name = (plugin) => `${plugin.sourceExport}${plugin.sourceModule .split('/')[plugin.sourceModule.split('/').length - 1].replace(/[^a-zA-Z0-9]/g, '')}`; const fileName = (plugin) => `${plugin.sourceModule}#${plugin.sourceExport}`; const originalName = (n) => `${n}${originalSuffix}`; @@ -121,8 +121,7 @@ async function generateInterceptor(interceptor, config, oldInterceptorSource) { .join(' wrapping '); if (isReplacePluginConfig(p)) { new RenameVisitor_1.RenameVisitor([originalName(p.targetExport)], (s) => s.replace(originalSuffix, disabledSuffix)).visitModule(ast); - carryProps.push(interceptorPropsName(name(p))); - result = `type ${interceptorPropsName(name(p))} = React.ComponentProps`; + carryProps.push(`React.ComponentProps`); pluginSee.push(`@see {${sourceName(name(p))}} for replacement of the original source (original source not used)`); } if (isReactPluginConfig(p)) { @@ -154,7 +153,7 @@ async function generateInterceptor(interceptor, config, oldInterceptorSource) { }) .filter((v) => !!v) .join('\n'); - const isComponent = plugins.every((p) => isReplacePluginConfig(p) || isReactPluginConfig(p)); + const isComponent = plugins.every((p) => isReactPluginConfig(p)); if (isComponent && plugins.some((p) => isMethodPluginConfig(p))) { throw new Error(`Cannot mix React and Method plugins for ${base} in ${dependency}.`); } diff --git a/packagesDev/next-config/src/interceptors/findOriginalSource.ts b/packagesDev/next-config/src/interceptors/findOriginalSource.ts index 74301d6491..4371de876f 100644 --- a/packagesDev/next-config/src/interceptors/findOriginalSource.ts +++ b/packagesDev/next-config/src/interceptors/findOriginalSource.ts @@ -32,6 +32,21 @@ function parseAndFindExport( break } } + + if (node.type === 'ExportNamedDeclaration') { + for (const specifier of node.specifiers) { + if (specifier.type === 'ExportSpecifier') { + if (specifier.exported?.value === findExport) return resolved + } else if (specifier.type === 'ExportDefaultSpecifier') { + // todo + } else if (specifier.type === 'ExportNamespaceSpecifier') { + // todo + } + } + } + + // todo: if (node.type === 'ExportDefaultDeclaration') {} + // todo: if (node.type === 'ExportDefaultExpression') {} } const exports = ast.body @@ -95,7 +110,7 @@ export function findOriginalSource( return { resolved: undefined, error: new Error( - `Can not find ${plug.targetModule}#${plug.sourceExport} for plugin ${plug.sourceModule}`, + `Plugin target not found ${plug.targetModule}#${plug.sourceExport} for plugin ${plug.sourceModule}#${plug.sourceExport}`, ), } } diff --git a/packagesDev/next-config/src/interceptors/generateInterceptor.ts b/packagesDev/next-config/src/interceptors/generateInterceptor.ts index 70414da1be..188a120d4c 100644 --- a/packagesDev/next-config/src/interceptors/generateInterceptor.ts +++ b/packagesDev/next-config/src/interceptors/generateInterceptor.ts @@ -223,7 +223,7 @@ export async function generateInterceptor( .filter((v) => !!v) .join('\n') - const isComponent = plugins.every((p) => isReplacePluginConfig(p) || isReactPluginConfig(p)) + const isComponent = plugins.every((p) => isReactPluginConfig(p)) if (isComponent && plugins.some((p) => isMethodPluginConfig(p))) { throw new Error(`Cannot mix React and Method plugins for ${base} in ${dependency}.`) } From 160cc91160662130aa467e591f32343f5c7531d9 Mon Sep 17 00:00:00 2001 From: Paul Hachmang Date: Tue, 30 Apr 2024 13:36:54 +0200 Subject: [PATCH 3/3] Move to an icons.ts file instead of icons/index.ts --- docs/framework/icons.md | 34 ++++++------- .../ProductFiltersProSortDirectionArrow.tsx | 6 +-- packages/next-ui/icons.ts | 50 +++++++++++++++++++ packages/next-ui/icons/index.ts | 48 ------------------ 4 files changed, 66 insertions(+), 72 deletions(-) create mode 100644 packages/next-ui/icons.ts delete mode 100644 packages/next-ui/icons/index.ts diff --git a/docs/framework/icons.md b/docs/framework/icons.md index 8684741977..55032eff52 100644 --- a/docs/framework/icons.md +++ b/docs/framework/icons.md @@ -160,13 +160,11 @@ imported from there (the `` component will convert the relative path to an absolute path) ```tsx -... +//... import customIcon from './my-custom-icon.svg' -... -return ( - -) +//... +return ``` To use a custom icon in your component, follow the same steps as described in @@ -177,27 +175,23 @@ the [previous paragraph](#using-a-different-icon-from-the-icon-pack). ## Using a different icon pack -To override all or multiple icons with your own, add an icon override array to -/theme.ts: +To override all or multiple icons with your own, you can write a replace plugin +to achieve this: ```tsx -// /components/theme.ts -import { iconCart, iconChat } from '@graphcommerce/next-ui' +// /plugins/icons/Icons.ts +import { PluginConfig } from '@graphcommerce/next-config' +import iconBasket from './basket.svg' import customCartIcon from './my-custom-cart-icon.svg' import customChatIcon from './my-custom-chat-icon.svg' -// ... -const createOverrides = (theme: Theme): Components => ({ - //... other component styling +export const config: PluginConfig = { + type: 'replace', + module: '@graphcommerce/next-ui', +} - IconSvg: { - overrides: [ - [iconCart, customCartIcon], - [iconChat, customChatIcon], - ], - }, -}) -// ... +export const iconShoppingBag = iconBasket +export const iconChart = iconBasket ``` All icons must meet the svg specifications as described above diff --git a/packages/magento-product/components/ProductFiltersPro/ProductFiltersProSortDirectionArrow.tsx b/packages/magento-product/components/ProductFiltersPro/ProductFiltersProSortDirectionArrow.tsx index 7dc43ea728..314172d11e 100644 --- a/packages/magento-product/components/ProductFiltersPro/ProductFiltersProSortDirectionArrow.tsx +++ b/packages/magento-product/components/ProductFiltersPro/ProductFiltersProSortDirectionArrow.tsx @@ -1,7 +1,5 @@ import { SortEnum } from '@graphcommerce/graphql-mesh' -import { IconSvg } from '@graphcommerce/next-ui' -import * as IconArrowDown from '@graphcommerce/next-ui/icons/arrow-down.svg' -import * as IconArrowUp from '@graphcommerce/next-ui/icons/arrow-up.svg' +import { IconSvg, iconArrowDown, iconArrowUp } from '@graphcommerce/next-ui' type Props = { sortDirection: SortEnum | null @@ -10,7 +8,7 @@ type Props = { export function ProductFiltersProSortDirectionArrow({ sortDirection }: Props) { return ( ) diff --git a/packages/next-ui/icons.ts b/packages/next-ui/icons.ts new file mode 100644 index 0000000000..f5b9874b0d --- /dev/null +++ b/packages/next-ui/icons.ts @@ -0,0 +1,50 @@ +export { default as iconArrowDown } from './icons/arrow-down.svg' +export { default as iconArrowBack } from './icons/arrow-left.svg' +export { default as iconArrowForward } from './icons/arrow-right.svg' +export { default as iconArrowUp } from './icons/arrow-up.svg' +export { default as iconShoppingBag } from './icons/bag.svg' +export { default as iconInvoice } from './icons/box-alt.svg' +export { default as iconBox } from './icons/box.svg' +export { default as iconOrderBefore } from './icons/calendar.svg' +export { default as iconCancelAlt } from './icons/cancel-alt.svg' +export { default as iconCartAdd } from './icons/cart-add.svg' +export { default as iconCart } from './icons/cart.svg' +export { default as iconChat } from './icons/chat-alt.svg' +export { default as iconCustomerService } from './icons/chat.svg' +export { default as iconChevronDown } from './icons/chevron-down.svg' +export { default as iconChevronBack, default as iconChevronLeft } from './icons/chevron-left.svg' +export { default as iconChevronRight } from './icons/chevron-right.svg' +export { default as iconChevronUp } from './icons/chevron-up.svg' +export { default as iconCirle } from './icons/circle.svg' +export { default as iconClose } from './icons/close.svg' +export { default as iconCompare } from './icons/compare-arrows.svg' +export { default as iconCreditCard, default as iconId } from './icons/credit-card.svg' +export { default as iconEllypsis } from './icons/ellypsis.svg' +export { default as iconEmail, default as iconEmailOutline } from './icons/envelope-alt.svg' +export { default as icon404 } from './icons/explore.svg' +export { default as iconEyeClosed } from './icons/eye-closed.svg' +export { default as iconEyeCrossed } from './icons/eye-crossed.svg' +export { default as iconEye } from './icons/eye.svg' +export { default as iconHeart } from './icons/favourite.svg' +export { default as iconMenu } from './icons/hamburger.svg' +export { default as iconParty } from './icons/happy-face.svg' +export { default as iconAddresses, default as iconHome } from './icons/home-alt.svg' +export { default as iconLanguage } from './icons/language.svg' +export { default as iconLocation } from './icons/location.svg' +export { default as iconLock } from './icons/lock.svg' +export { default as iconFullscreen } from './icons/maximise.svg' +export { default as iconFullscreenExit } from './icons/minimise.svg' +export { default as iconMin } from './icons/minus.svg' +export { default as iconMoon } from './icons/moon.svg' +export { default as iconNewspaper } from './icons/news.svg' +export { default as iconCheckmark } from './icons/ok.svg' +export { default as iconPerson } from './icons/person-alt.svg' +export { default as iconPlay } from './icons/play.svg' +export { default as iconPlus } from './icons/plus.svg' +export { default as iconShutdown } from './icons/power.svg' +export { default as iconRefresh } from './icons/refresh.svg' +export { default as iconSadFace } from './icons/sad-face.svg' +export { default as iconSearch } from './icons/search.svg' +export { default as iconPhone } from './icons/smartphone.svg' +export { default as iconStar } from './icons/star.svg' +export { default as iconSun } from './icons/sun.svg' diff --git a/packages/next-ui/icons/index.ts b/packages/next-ui/icons/index.ts deleted file mode 100644 index 0618dc9265..0000000000 --- a/packages/next-ui/icons/index.ts +++ /dev/null @@ -1,48 +0,0 @@ -export { default as iconArrowBack } from './arrow-left.svg' -export { default as iconArrowForward } from './arrow-right.svg' -export { default as iconShoppingBag } from './bag.svg' -export { default as iconInvoice } from './box-alt.svg' -export { default as iconBox } from './box.svg' -export { default as iconOrderBefore } from './calendar.svg' -export { default as iconCancelAlt } from './cancel-alt.svg' -export { default as iconCartAdd } from './cart-add.svg' -export { default as iconCart } from './cart.svg' -export { default as iconChat } from './chat-alt.svg' -export { default as iconCustomerService } from './chat.svg' -export { default as iconChevronDown } from './chevron-down.svg' -export { default as iconChevronBack, default as iconChevronLeft } from './chevron-left.svg' -export { default as iconChevronRight } from './chevron-right.svg' -export { default as iconChevronUp } from './chevron-up.svg' -export { default as iconCirle } from './circle.svg' -export { default as iconClose } from './close.svg' -export { default as iconCreditCard, default as iconId } from './credit-card.svg' -export { default as iconEllypsis } from './ellypsis.svg' -export { default as iconEmail, default as iconEmailOutline } from './envelope-alt.svg' -export { default as icon404 } from './explore.svg' -export { default as iconEyeClosed } from './eye-closed.svg' -export { default as iconEyeCrossed } from './eye-crossed.svg' -export { default as iconEye } from './eye.svg' -export { default as iconHeart } from './favourite.svg' -export { default as iconMenu } from './hamburger.svg' -export { default as iconParty } from './happy-face.svg' -export { default as iconAddresses, default as iconHome } from './home-alt.svg' -export { default as iconLanguage } from './language.svg' -export { default as iconLocation } from './location.svg' -export { default as iconLock } from './lock.svg' -export { default as iconFullscreen } from './maximise.svg' -export { default as iconFullscreenExit } from './minimise.svg' -export { default as iconMin } from './minus.svg' -export { default as iconMoon } from './moon.svg' -export { default as iconNewspaper } from './news.svg' -export { default as iconCheckmark } from './ok.svg' -export { default as iconPerson } from './person-alt.svg' -export { default as iconPlay } from './play.svg' -export { default as iconPlus } from './plus.svg' -export { default as iconShutdown } from './power.svg' -export { default as iconRefresh } from './refresh.svg' -export { default as iconSadFace } from './sad-face.svg' -export { default as iconSearch } from './search.svg' -export { default as iconPhone } from './smartphone.svg' -export { default as iconStar } from './star.svg' -export { default as iconSun } from './sun.svg' -export { default as iconCompare } from './compare-arrows.svg'