diff --git a/apps/widget-configurator/src/app/embedDialog/const.ts b/apps/widget-configurator/src/app/embedDialog/const.ts index 3d07acb119..4b7be2e4b5 100644 --- a/apps/widget-configurator/src/app/embedDialog/const.ts +++ b/apps/widget-configurator/src/app/embedDialog/const.ts @@ -16,6 +16,11 @@ export const COMMENTS_BY_PARAM_NAME: Record = { interfaceFeeBips: 'Fill the form above if you are interested', } +export const COMMENTS_BY_PARAM_NAME_TYPESCRIPT: Record = { + tradeType: 'TradeType.SWAP, TradeType.LIMIT or TradeType.ADVANCED', + enabledTradeTypes: 'TradeType.SWAP, TradeType.LIMIT and/or TradeType.ADVANCED', +} + export const VALUES_BY_PARAM_NAME: Record = { provider: 'window.ethereum', } @@ -27,3 +32,5 @@ export const SANITIZE_PARAMS = { } export const REMOVE_PARAMS: (keyof CowSwapWidgetParams)[] = ['env'] + +export const IMPORT_STATEMENT = `import { CowSwapWidget, CowSwapWidgetParams, TradeType }` diff --git a/apps/widget-configurator/src/app/embedDialog/index.tsx b/apps/widget-configurator/src/app/embedDialog/index.tsx index 297295a389..9c767d345b 100644 --- a/apps/widget-configurator/src/app/embedDialog/index.tsx +++ b/apps/widget-configurator/src/app/embedDialog/index.tsx @@ -1,10 +1,12 @@ -import React, { SyntheticEvent, useEffect, useMemo, useRef, useState } from 'react' +import React, { SyntheticEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react' import HTMLIcon from '@cowprotocol/assets/cow-swap/html.svg' import JSIcon from '@cowprotocol/assets/cow-swap/js.svg' import ReactIcon from '@cowprotocol/assets/cow-swap/react.svg' +import TSIcon from '@cowprotocol/assets/cow-swap/ts.svg' import { CowSwapWidgetProps } from '@cowprotocol/widget-react' +import { Tab } from '@mui/material' import MuiAlert, { AlertProps } from '@mui/material/Alert' import Box from '@mui/material/Box' import Button from '@mui/material/Button' @@ -13,27 +15,66 @@ import DialogActions from '@mui/material/DialogActions' import DialogContent from '@mui/material/DialogContent' import DialogTitle from '@mui/material/DialogTitle' import Snackbar from '@mui/material/Snackbar' -import Tab from '@mui/material/Tab' import Tabs from '@mui/material/Tabs' import SVG from 'react-inlinesvg' import SyntaxHighlighter from 'react-syntax-highlighter' // eslint-disable-next-line no-restricted-imports import { nightOwl } from 'react-syntax-highlighter/dist/esm/styles/hljs' -import { reactExample } from './utils/reactExample' -import { vanilaNpmExample } from './utils/vanilaNpmExample' -import { vanillaNoDepsExample } from './utils/vanillaNoDepsExample' +import { vanillaNoDepsExample } from './utils/htmlExample' +import { jsExample } from './utils/jsExample' +import { reactTsExample } from './utils/reactTsExample' +import { tsExample } from './utils/tsExample' import { copyEmbedCodeGA, viewEmbedCodeGA } from '../analytics' +interface TabInfo { + id: number + label: string + language: string + snippetFromParams(params: CowSwapWidgetProps['params']): string + icon: string +} + +const TABS: TabInfo[] = [ + { + id: 0, + label: 'React Typescript', + language: 'typescript', + snippetFromParams: reactTsExample, + icon: ReactIcon, + }, + { + id: 1, + label: 'Typescript', + language: 'typescript', + snippetFromParams: tsExample, + icon: TSIcon, + }, + { + id: 2, + label: 'Javascript', + language: 'javascript', + snippetFromParams: jsExample, + icon: JSIcon, + }, + { + id: 3, + label: 'Pure HTML', + language: 'html', + snippetFromParams: vanillaNoDepsExample, + icon: HTMLIcon, + }, +] + const Alert = React.forwardRef(function Alert(props, ref) { return }) -function a11yProps(index: number) { +function a11yProps(id: number) { return { - id: `simple-tab-${index}`, - 'aria-controls': `simple-tabpanel-${index}`, + id: `simple-tab-${id}`, + 'aria-controls': `simple-tabpanel-${id}`, } } @@ -45,7 +86,8 @@ export interface EmbedDialogProps { export function EmbedDialog({ params, open, handleClose }: EmbedDialogProps) { const [scroll, setScroll] = useState('paper') - const [currentTab, setCurrentTab] = useState(0) + const [tabInfo, setCurrentTabInfo] = useState(TABS[0]) + const { id, language, snippetFromParams } = tabInfo const descriptionElementRef = useRef(null) const [snackbarOpen, setSnackbarOpen] = useState(false) @@ -74,12 +116,10 @@ export function EmbedDialog({ params, open, handleClose }: EmbedDialogProps) { }, [open]) const code = useMemo(() => { - if (currentTab === 0) return vanilaNpmExample(params) - if (currentTab === 1) return reactExample(params) - if (currentTab === 2) return vanillaNoDepsExample(params) + return snippetFromParams(params) + }, [snippetFromParams, params]) - return '' - }, [currentTab, params]) + const onChangeTab = useCallback((_event: SyntheticEvent, newValue: TabInfo) => setCurrentTabInfo(newValue), []) return (
@@ -97,9 +137,9 @@ export function EmbedDialog({ params, open, handleClose }: EmbedDialogProps) { setCurrentTab(newValue)} - aria-label="configuration tabs" + value={tabInfo} + onChange={onChangeTab} + aria-label="languages" sx={{ '& .MuiTab-iconWrapper': { height: '16px', @@ -111,17 +151,25 @@ export function EmbedDialog({ params, open, handleClose }: EmbedDialogProps) { }, }} > - } iconPosition="start" {...a11yProps(0)} /> - } iconPosition="start" {...a11yProps(1)} /> - } iconPosition="start" {...a11yProps(2)} /> + {TABS.map((info) => { + return ( + } + value={info} + {...a11yProps(info.id)} + /> + ) + })} -
+
diff --git a/apps/widget-configurator/src/app/embedDialog/utils/formatParameters.ts b/apps/widget-configurator/src/app/embedDialog/utils/formatParameters.ts index 3145602f4b..9d034289fc 100644 --- a/apps/widget-configurator/src/app/embedDialog/utils/formatParameters.ts +++ b/apps/widget-configurator/src/app/embedDialog/utils/formatParameters.ts @@ -2,25 +2,49 @@ import { CowSwapWidgetParams } from '@cowprotocol/widget-lib' import { sanitizeParameters } from './sanitizeParameters' -import { COMMENTS_BY_PARAM_NAME, REMOVE_PARAMS, VALUES_BY_PARAM_NAME } from '../const' +import { + COMMENTS_BY_PARAM_NAME, + COMMENTS_BY_PARAM_NAME_TYPESCRIPT, + REMOVE_PARAMS, + VALUES_BY_PARAM_NAME, +} from '../const' -export function formatParameters(params: CowSwapWidgetParams, padLeft = 0): string { +export function formatParameters(params: CowSwapWidgetParams, padLeft = 0, isTypescript: boolean): string { const paramsSanitized = sanitizeParameters(params) REMOVE_PARAMS.forEach((propName) => { delete paramsSanitized[propName] }) + + // Stringify params const formattedParams = JSON.stringify(paramsSanitized, null, 4) // Add comments - const resultWithComments = Object.keys(COMMENTS_BY_PARAM_NAME).reduce((acc, propName) => { - return acc.replace(new RegExp(`"${propName}".*$`, 'gm'), `$& // ${COMMENTS_BY_PARAM_NAME[propName]}`) + const commentsByParamName = isTypescript + ? { ...COMMENTS_BY_PARAM_NAME, ...COMMENTS_BY_PARAM_NAME_TYPESCRIPT } + : COMMENTS_BY_PARAM_NAME + + const resultWithComments = Object.keys(commentsByParamName).reduce((acc, propName) => { + return acc.replace(new RegExp(`"${propName}".*$`, 'gm'), `$& // ${commentsByParamName[propName]}`) }, formattedParams) // Add values - const resultWithValues = Object.keys(VALUES_BY_PARAM_NAME).reduce((acc, propName) => { - return acc.replace(new RegExp(`("${propName}".* )(".*")(.*)$`, 'gm'), `$1${VALUES_BY_PARAM_NAME[propName]}$3`) + const tradeTypeValue = isTypescript ? 'TradeType.' + params.tradeType?.toUpperCase() : `"${params.tradeType}"` + const valuesByParamName: Record = tradeTypeValue + ? { ...VALUES_BY_PARAM_NAME, tradeType: tradeTypeValue } + : VALUES_BY_PARAM_NAME + + let resultWithValues = Object.keys(valuesByParamName).reduce((acc, propName) => { + return acc.replace(new RegExp(`("${propName}".* )(".*")(.*)$`, 'gm'), `$1${valuesByParamName[propName]}$3`) }, resultWithComments) + // Fix the enabledTradeTypes + if (isTypescript) { + resultWithValues = resultWithValues.replace( + new RegExp(/^(\s*)"(\w*)"(,?)$/gm), + (_match, space, tradeType, comma) => space + 'TradeType.' + tradeType.toUpperCase() + comma + ) + } + if (padLeft === 0) { return resultWithValues } diff --git a/apps/widget-configurator/src/app/embedDialog/utils/vanillaNoDepsExample.ts b/apps/widget-configurator/src/app/embedDialog/utils/htmlExample.ts similarity index 92% rename from apps/widget-configurator/src/app/embedDialog/utils/vanillaNoDepsExample.ts rename to apps/widget-configurator/src/app/embedDialog/utils/htmlExample.ts index b59999f054..ec4ad1c706 100644 --- a/apps/widget-configurator/src/app/embedDialog/utils/vanillaNoDepsExample.ts +++ b/apps/widget-configurator/src/app/embedDialog/utils/htmlExample.ts @@ -16,7 +16,7 @@ export function vanillaNoDepsExample(params: CowSwapWidgetParams): string {
diff --git a/apps/widget-configurator/src/app/embedDialog/utils/vanilaNpmExample.ts b/apps/widget-configurator/src/app/embedDialog/utils/jsExample.ts similarity index 61% rename from apps/widget-configurator/src/app/embedDialog/utils/vanilaNpmExample.ts rename to apps/widget-configurator/src/app/embedDialog/utils/jsExample.ts index a6916dab77..82da5d820e 100644 --- a/apps/widget-configurator/src/app/embedDialog/utils/vanilaNpmExample.ts +++ b/apps/widget-configurator/src/app/embedDialog/utils/jsExample.ts @@ -4,14 +4,14 @@ import { formatParameters } from './formatParameters' import { COMMENTS_BEFORE_PARAMS } from '../const' -export function vanilaNpmExample(params: CowSwapWidgetParams): string { +export function jsExample(params: CowSwapWidgetParams): string { return ` -import { CowSwapWidgetParams, cowSwapWidget } from '@cowprotocol/widget-lib' +import { cowSwapWidget } from '@cowprotocol/widget-lib' const container = document.getElementById('') // ${COMMENTS_BEFORE_PARAMS} -const params: CowSwapWidgetParams = ${formatParameters(params)} +const params = ${formatParameters(params, 0, false)} const updateWidget = cowSwapWidget(container, params) ` diff --git a/apps/widget-configurator/src/app/embedDialog/utils/reactExample.ts b/apps/widget-configurator/src/app/embedDialog/utils/reactExample.ts deleted file mode 100644 index 771874311d..0000000000 --- a/apps/widget-configurator/src/app/embedDialog/utils/reactExample.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { CowSwapWidgetParams } from '@cowprotocol/widget-lib' - -import { formatParameters } from './formatParameters' - -import { COMMENTS_BEFORE_PARAMS } from '../const' - -export function reactExample(params: CowSwapWidgetParams): string { - return ` -import { CowSwapWidget, CowSwapWidgetParams } from '@cowprotocol/widget-react' - -// ${COMMENTS_BEFORE_PARAMS} -const params: CowSwapWidgetParams = ${formatParameters(params)} - -function App() { - return ( - - ) -} -` -} diff --git a/apps/widget-configurator/src/app/embedDialog/utils/reactTsExample.ts b/apps/widget-configurator/src/app/embedDialog/utils/reactTsExample.ts new file mode 100644 index 0000000000..0a438cec6e --- /dev/null +++ b/apps/widget-configurator/src/app/embedDialog/utils/reactTsExample.ts @@ -0,0 +1,20 @@ +import type { CowSwapWidgetParams } from '@cowprotocol/widget-lib' + +import { formatParameters } from './formatParameters' + +import { COMMENTS_BEFORE_PARAMS, IMPORT_STATEMENT } from '../const' + +export function reactTsExample(params: CowSwapWidgetParams): string { + return ` +${IMPORT_STATEMENT} from '@cowprotocol/widget-react' + +// ${COMMENTS_BEFORE_PARAMS} +const params: CowSwapWidgetParams = ${formatParameters(params, 0, true)} + +function App() { + return ( + + ) +} +` +} diff --git a/apps/widget-configurator/src/app/embedDialog/utils/tsExample.ts b/apps/widget-configurator/src/app/embedDialog/utils/tsExample.ts new file mode 100644 index 0000000000..2cb3b462d8 --- /dev/null +++ b/apps/widget-configurator/src/app/embedDialog/utils/tsExample.ts @@ -0,0 +1,18 @@ +import type { CowSwapWidgetParams } from '@cowprotocol/widget-lib' + +import { formatParameters } from './formatParameters' + +import { COMMENTS_BEFORE_PARAMS, IMPORT_STATEMENT as TS_IMPORT_STATEMENT } from '../const' + +export function tsExample(params: CowSwapWidgetParams): string { + return ` +${TS_IMPORT_STATEMENT} from '@cowprotocol/widget-lib' + +const container = document.getElementById('') + +// ${COMMENTS_BEFORE_PARAMS} +const params: CowSwapWidgetParams = ${formatParameters(params, 0, true)} + +const updateWidget = cowSwapWidget(container, params) + ` +} diff --git a/libs/assets/src/cow-swap/ts.svg b/libs/assets/src/cow-swap/ts.svg new file mode 100644 index 0000000000..a46d53d49f --- /dev/null +++ b/libs/assets/src/cow-swap/ts.svg @@ -0,0 +1 @@ + \ No newline at end of file