Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Anands review and thoughts #105

Open
wants to merge 10 commits into
base: syncing-workspace-and-code
Choose a base branch
from
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -41,15 +41,18 @@
"redux-persist": "^6.0.0",
"redux-undo": "^1.0.0",
"reselect": "^4.0.0",
"typescript": "^3.7.5",
"typescript": "4.2.2",
"webfontloader": "^1.6.28"
},
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired --max_old_space_size=4096 build",
"test": "react-app-rewired test --env=jsdom",
"analyze": "BUNDLE_VISUALIZE=1 react-app-rewired build",
"docs": "jsdoc -c jsdoc.conf.json"
"source-bloat": "source-map-explorer 'build/static/js/*.js'",
"docs": "jsdoc -c jsdoc.conf.json",
"typecheck": "tsc",
"typecheck:watch": "tsc -w"
},
"eslintConfig": {
"extends": "react-app"
@@ -87,6 +90,7 @@
"lint-staged": "^10.0.7",
"pretty-quick": "^2.0.1",
"react-app-rewired": "^2.1.5",
"source-map-explorer": "^2.5.2",
"typedoc": "^0.16.9"
},
"husky": {
31 changes: 16 additions & 15 deletions src/babel-plugins/add-component-plugin.ts
Original file line number Diff line number Diff line change
@@ -37,21 +37,22 @@ const addComponentPlugin = (
const openingElement = path.node.openingElement

const visitedComponentId = getComponentId(openingElement)
if (visitedComponentId && visitedComponentId === parentId) {
// Change the JSX element in the string to node template
const node = template.ast(componentCode, {
plugins: ['jsx'],
}).expression

const newLineText = t.jsxText('\n')

// Add to the children of the parent component
if (path.node.children.length > 0) {
path.node.children.push(node)
path.node.children.push(newLineText)
} else {
path.node.children = [newLineText, node, newLineText]
}
if (visitedComponentId && visitedComponentId !== parentId) {
return
}
// Change the JSX element in the string to node template
const node = template.ast(componentCode, {
plugins: ['jsx'],
}).expression

const newLineText = t.jsxText('\n')

// Add to the children of the parent component
if (path.node.children.length > 0) {
path.node.children.push(node)
path.node.children.push(newLineText)
} else {
path.node.children = [newLineText, node, newLineText]
}
},
},
46 changes: 25 additions & 21 deletions src/babel-plugins/add-custom-component-plugin.ts
Original file line number Diff line number Diff line change
@@ -23,6 +23,8 @@ const addCustomComponentPlugin = (

// If the value of the prop is a component-id, then the box component should be added.
// or else its respective value will be added.
//TODO remove scope and pass as argument
//TODO break into two function, filter, then map
const defaultPropsProvider = () => {
return defaultProps
.filter(prop => prop.name !== 'children')
@@ -67,31 +69,33 @@ const addCustomComponentPlugin = (
const openingElement = path.node.openingElement

const visitedComponentId = getComponentId(openingElement)
if (visitedComponentId && visitedComponentId === parentId) {
let component: string = ``
if (visitedComponentId && visitedComponentId !== parentId) {
return
}

// If the component is container component, the element will be <Card></Card>
// If the component is not a container component, the element will be <Card />
let component: string = ``

if (isContainerComponent) {
component = `<${type} compId="${componentId}" ${defaultPropsProvider()}></${type}>`
} else {
component = `<${type} compId="${componentId}" ${defaultPropsProvider()}/>`
}
// If the component is container component, the element will be <Card></Card>
// If the component is not a container component, the element will be <Card />

// Change the JSX element in the string to node template
const node = template.ast(component, {
plugins: ['jsx'],
}).expression
const newLineText = t.jsxText('\n')
if (isContainerComponent) {
component = `<${type} compId="${componentId}" ${defaultPropsProvider()}></${type}>`
} else {
component = `<${type} compId="${componentId}" ${defaultPropsProvider()}/>`
}

// Add to the children of the parent component
if (path.node.children.length > 0) {
path.node.children.push(node)
path.node.children.push(newLineText)
} else {
path.node.children = [newLineText, node, newLineText]
}
// Change the JSX element in the string to node template
const node = template.ast(component, {
plugins: ['jsx'],
}).expression
const newLineText = t.jsxText('\n')

// Add to the children of the parent component
if (path.node.children.length > 0) {
path.node.children.push(node)
path.node.children.push(newLineText)
} else {
path.node.children = [newLineText, node, newLineText]
}
},
},
27 changes: 13 additions & 14 deletions src/babel-plugins/add-prop-in-all-instances.ts
Original file line number Diff line number Diff line change
@@ -19,23 +19,22 @@ const addPropInAllInstances = (
visitor: {
JSXOpeningElement(path: any) {
const visitedComponentName = path.node.name.name
if (visitedComponentName !== componentName) return

if (visitedComponentName === componentName) {
if (boxId) {
const boxComponent = `<Box compId="${boxId}"></Box>`
if (boxId) {
const boxComponent = `<Box compId="${boxId}"></Box>`

const element = getJSXElement(boxComponent)
const element = getJSXElement(boxComponent)

const jsxAttribute = t.jsxAttribute(
t.jsxIdentifier(propName),
t.jsxExpressionContainer(element),
)
path.node.attributes.push(jsxAttribute)
} else {
const jsxAttribute = toJsxAttribute(propName, propValue)
path.node.attributes.push(jsxAttribute)
}
} else return
const jsxAttribute = t.jsxAttribute(
t.jsxIdentifier(propName),
t.jsxExpressionContainer(element),
)
path.node.attributes.push(jsxAttribute)
} else {
const jsxAttribute = toJsxAttribute(propName, propValue)
path.node.attributes.push(jsxAttribute)
}
},
},
}
3 changes: 2 additions & 1 deletion src/components/editor/ComponentPreview.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//@ts-nocheck
import React from 'react'
import { render } from '@testing-library/react'
import { init } from '@rematch/core'
@@ -87,7 +88,7 @@ const componentsToTest = [
'MenuMeta',
]

test.each(componentsToTest)('Component Preview for %s', componentName => {
test.each(componentsToTest)('Component Preview for %s', (componentName) => {
// const spy = jest.spyOn(global.console, 'error')
// @ts-ignore
const store = init(storeConfig)
43 changes: 20 additions & 23 deletions src/components/editor/PreviewContainer.tsx
Original file line number Diff line number Diff line change
@@ -2,20 +2,12 @@ import React, { FunctionComponent, ComponentClass, Suspense } from 'react'
import { useInteractive } from '../../hooks/useInteractive'
import { Box } from '@chakra-ui/core'
import findAndReplaceExposedPropValue from '../../utils/findAndReplaceExposedPropValue'
import stringToIconConvertor from '../../utils/stringToIconConvertor'
import reactIcon from '../../utils/stringToIconConvertor'
import { useDropComponent } from '../../hooks/useDropComponent'
import { CopyIcon } from '@chakra-ui/icons'

export const isPropRelatedToIcon = (type: string, propName: string) => {
if (
(type === 'Icon' && propName === 'as') ||
propName === 'icon' ||
propName === 'leftIcon' ||
propName === 'rightIcon'
)
return true
return false
}
import {
isInlineIconComponent,
isInlineIconString,
} from '../../utils/isInlineIcon'

const PreviewContainer: React.FC<{
component: IComponent
@@ -51,21 +43,26 @@ const PreviewContainer: React.FC<{

//Converting the icon in string to reactElement
Object.keys(propsKeyValue).forEach((key: string) => {
if (isPropRelatedToIcon(component.type, key))
propsKeyValue[key] = (
<Suspense fallback={<CopyIcon />}>
{stringToIconConvertor(key, propsKeyValue[key])}
</Suspense>
)
if (isInlineIconString(component.type, key)) {
propsKeyValue[key] = reactIcon(propsKeyValue[key])
}
if (isInlineIconComponent(key)) {
propsKeyValue[key] = React.createElement(reactIcon(propsKeyValue[key]))
}
})

console.log(propsKeyValue)

const children = React.createElement(type, {
let props = {
...propsKeyValue,
...forwardedProps,
ref: drop(ref),
})
}
if (component.type === 'Icon') {
delete props.ref
}

const children = (
<Suspense fallback={'.'}>{React.createElement(type, props)}</Suspense>
)

if (isBoxWrapped) {
let boxProps: any = {}
15 changes: 1 addition & 14 deletions src/components/editor/previews/CustomComponentPreview.tsx
Original file line number Diff line number Diff line change
@@ -5,7 +5,6 @@ import ComponentPreview from '../ComponentPreview'
import { useInteractive } from '../../../hooks/useInteractive'
import {
getChildrenBy,
getPropsBy,
checkIsContainerComponent,
} from '../../../core/selectors/components'
import findAndReplaceExposedPropValue from '../../../utils/findAndReplaceExposedPropValue'
@@ -51,18 +50,6 @@ const CustomComponentPreview: React.FC<{

const componentChildren = useSelector(getChildrenBy(component.type))

//width of outer container will be the with of the child component
let widthProp = useSelector(getPropsBy(componentChildren[0])).find(
prop => prop.name === 'width',
)
if (widthProp?.derivedFromComponentType) {
widthProp = componentProps.find(
prop => prop.name === widthProp?.derivedFromPropName,
)
}

const width = widthProp ? widthProp.value : '100%'

const propsKeyValue = findAndReplaceExposedPropValue(
componentProps,
customProps,
@@ -73,7 +60,7 @@ const CustomComponentPreview: React.FC<{
)

return (
<Box {...interactionProps} ref={drop(ref)} width={width}>
<Box {...interactionProps} ref={drop(ref)}>
{componentChildren.map((key: string) => (
<ComponentPreview
key={key}
34 changes: 14 additions & 20 deletions src/components/editor/previews/EditablePreviewContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import React, { FunctionComponent, ComponentClass, Suspense } from 'react'
import { Box } from '@chakra-ui/core'
import { CopyIcon } from '@chakra-ui/icons'

import { useInteractive } from '../../../hooks/useInteractive'
import findAndReplaceExposedPropValue from '../../../utils/findAndReplaceExposedPropValue'
import {
@@ -15,10 +13,13 @@ import {
} from '../../../core/selectors/components'
import useDispatch from '../../../hooks/useDispatch'
import { useDropComponent } from '../../../hooks/useDropComponent'
import { isPropRelatedToIcon } from '../PreviewContainer'
import stringToIconConvertor from '../../../utils/stringToIconConvertor'
import reactIcon from '../../../utils/stringToIconConvertor'
import { useForm } from '../../../hooks/useForm'
import { acceptTypes, rootComponents } from '../../../utils/editor'
import {
isInlineIconComponent,
isInlineIconString,
} from '../../../utils/isInlineIcon'

const EditablePreviewContainer: React.FC<{
component: IComponent
@@ -99,21 +100,12 @@ const EditablePreviewContainer: React.FC<{

//Converting the icon in string to reactElement
Object.keys(propsKeyValue).forEach((key: string) => {
if (isPropRelatedToIcon(component.type, key)) {
const Icon = stringToIconConvertor(key, propsKeyValue[key])
console.log(Icon)
console.log(<CopyIcon />)

propsKeyValue[key] = (
<Suspense fallback={<CopyIcon />}>
{stringToIconConvertor(key, propsKeyValue[key])}
</Suspense>
)
}
if (isInlineIconString(component.type, key))
propsKeyValue[key] = reactIcon(propsKeyValue[key])
if (isInlineIconComponent(key))
propsKeyValue[key] = React.createElement(reactIcon(propsKeyValue[key]))
})

console.log(propsKeyValue)

const Element = React.createElement(type, {
...propsKeyValue,
...forwardedProps,
@@ -138,9 +130,11 @@ const EditablePreviewContainer: React.FC<{
/>,
)

return inputTextFocused && component.id === selectedId
? contentEditableElement
: Element
return inputTextFocused && component.id === selectedId ? (
contentEditableElement
) : (
<Suspense fallback={'.'}>{Element}</Suspense>
)
}

export default EditablePreviewContainer
5 changes: 3 additions & 2 deletions src/components/inspector/controls/IconControl.tsx
Original file line number Diff line number Diff line change
@@ -12,17 +12,18 @@ type IconControlProps = {

const IconControl: React.FC<IconControlProps> = ({ name, label }) => {
const { propId, propValue } = usePropsSelector(name)
const iconsArray = Object.keys(icons).filter(icon => icon !== 'createIcon')
const iconsArray = Object.keys(icons).filter((icon) => icon !== 'createIcon')

return (
<FormControl label={label} htmlFor={name}>
<ComboBox
id={propId}
editable={false}
options={iconsArray}
value={propValue}
name={name}
enableAutoComplete={true}
renderOptions={option => {
renderOptions={(option) => {
const iconName = option
// @ts-ignore
const Icon = React.createElement(icons[iconName])
1 change: 1 addition & 0 deletions src/core/models/components.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//@ts-nocheck
import components, {
ComponentsState,
INITIAL_COMPONENTS,
7 changes: 7 additions & 0 deletions src/utils/isInlineIcon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const isInlineIconString = (componentName: string, propName: string) => {
return componentName === 'Icon' && propName === 'as'
}

export const isInlineIconComponent = (prop: string) => {
return ['leftIcon', 'icon', 'rightIcon'].includes(prop)
}
5 changes: 3 additions & 2 deletions src/utils/recursive.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//@ts-nocheck
import { generateId } from './generateId'
import { duplicateComponent, deleteComponent } from './recursive'

@@ -67,10 +68,10 @@ describe('recursive functions', () => {
}

const avatars = Object.keys(finalTree).filter(
compKey => finalTree[compKey].type === 'Avatar',
(compKey) => finalTree[compKey].type === 'Avatar',
)
const boxes = Object.keys(finalTree).filter(
compKey => finalTree[compKey].type === 'Box',
(compKey) => finalTree[compKey].type === 'Box',
)

expect(avatars.length).toEqual(2)
Loading