Skip to content

Commit

Permalink
Even unparsed components should be added to the insert menu when they…
Browse files Browse the repository at this point in the history
… have component annotations (#5741)

* Any kind of exported object can be in the insert menu if it has component annotations

* Add tests and fixes

* Rename
  • Loading branch information
gbalint authored May 24, 2024
1 parent 467422b commit 37f29eb
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 16 deletions.
81 changes: 79 additions & 2 deletions editor/src/components/editor/export-utils.spec.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { isParseSuccess, parseFailure, unparsed } from '../../core/shared/project-file-types'
import { emptySet } from '../../core/shared/set-utils'
import { parseCode } from '../../core/workers/parser-printer/parser-printer'
import { defaultComponentDescriptor, ComponentDescriptorDefaults } from '../custom-code/code-file'
import { getExportedComponentImports } from './export-utils'

describe('getExportedComponentImports', () => {
it('returns null for an unparsed value', () => {
const actualResult = getExportedComponentImports('/src/app.js', '/src/index.js', unparsed)
const actualResult = getExportedComponentImports('/src/app.js', '/src/index.js', unparsed, {})
expect(actualResult).toMatchInlineSnapshot(`null`)
})
it('returns null for a parse failure', () => {
const actualResult = getExportedComponentImports(
'/src/app.js',
'/src/index.js',
parseFailure(null, null, 'Parse test failure.', []),
{},
)
expect(actualResult).toMatchInlineSnapshot(`null`)
})
Expand All @@ -32,7 +34,62 @@ export var Whatever = (props) => {
)
expect(isParseSuccess(parseResult)).toEqual(true)

const actualResult = getExportedComponentImports('/src/app.js', '/src/index.js', parseResult)
const actualResult = getExportedComponentImports(
'/src/app.js',
'/src/index.js',
parseResult,
{},
)
expect(actualResult).toMatchInlineSnapshot(`
Array [
Object {
"importsToAdd": Object {
"/src/index.js": Object {
"importedAs": null,
"importedFromWithin": Array [
Object {
"alias": "Whatever",
"name": "Whatever",
},
],
"importedWithName": null,
},
},
"listingName": "Whatever",
},
]
`)
})
it('returns exported non-component if it has property controls info', () => {
const codeForFile = `import React from "react";
export var Whatever = 'something'`
const parseResult = parseCode(
'/src/index.js',
codeForFile,
null,
emptySet(),
'do-not-apply-steganography',
)
expect(isParseSuccess(parseResult)).toEqual(true)

const propertyControlsInfo = {
'/src/index': {
Whatever: {
properties: {},
supportsChildren: false,
preferredChildComponents: [],
variants: [],
source: defaultComponentDescriptor(),
...ComponentDescriptorDefaults,
},
},
}
const actualResult = getExportedComponentImports(
'/src/app.js',
'/src/index.js',
parseResult,
propertyControlsInfo,
)
expect(actualResult).toMatchInlineSnapshot(`
Array [
Object {
Expand All @@ -53,4 +110,24 @@ export var Whatever = (props) => {
]
`)
})
it('doesnt return exported non-component when it doesnt have property controls info', () => {
const codeForFile = `import React from "react";
export var Whatever = 'something'`
const parseResult = parseCode(
'/src/index.js',
codeForFile,
null,
emptySet(),
'do-not-apply-steganography',
)
expect(isParseSuccess(parseResult)).toEqual(true)

const actualResult = getExportedComponentImports(
'/src/app.js',
'/src/index.js',
parseResult,
{},
)
expect(actualResult).toMatchInlineSnapshot(`Array []`)
})
})
40 changes: 30 additions & 10 deletions editor/src/components/editor/export-utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { elementUsesProperty } from '../../core/model/element-template-utils'
import { BakedInStoryboardVariableName } from '../../core/model/scene-utils'
import { propertyControlsForComponentInFile } from '../../core/property-controls/property-controls-utils'
import type { UtopiaJSXComponent } from '../../core/shared/element-template'
import { isUtopiaJSXComponent } from '../../core/shared/element-template'
import { dropFileExtension } from '../../core/shared/file-utils'
import type {
ImportDetails,
Imports,
Expand All @@ -14,6 +16,7 @@ import {
importDetails,
} from '../../core/shared/project-file-types'
import { emptyImports } from '../../core/workers/common/project-file-utils'
import type { PropertyControlsInfo } from '../custom-code/code-file'
import { StoryboardFilePath } from './store/editor-state'

interface ExportedComponentDetail {
Expand Down Expand Up @@ -44,6 +47,7 @@ export function getExportedComponentImportsFromParseSuccess(
originatingPath: string,
fullPath: string,
success: ParseSuccess,
propertyControlsInfo: PropertyControlsInfo,
): ExportedComponentImports {
const pathLastPart = pathLastPartWithoutExtension(fullPath)
let result: ExportedComponentImports = []
Expand All @@ -58,17 +62,27 @@ export function getExportedComponentImportsFromParseSuccess(
listingName: string,
importDetailsToAdd: ImportDetails,
): void {
for (const topLevelElement of success.topLevelElements) {
if (
const isParsedComponent = success.topLevelElements.some(
(topLevelElement) =>
isUtopiaJSXComponent(topLevelElement) &&
topLevelElement.name === elementMatchesName &&
!isStoryboard(topLevelElement)
) {
// Don't add an import if this is from the same file.
const importsToAdd =
originatingPath === fullPath ? emptyImports() : { [fullPath]: importDetailsToAdd }
result.push(exportedComponentDetail(importsToAdd, listingName))
}
!isStoryboard(topLevelElement),
)

const pathWithoutExtension = dropFileExtension(fullPath)
const propertyControls = propertyControlsForComponentInFile(
listingName,
pathWithoutExtension,
propertyControlsInfo,
)

const hasPropertyControl = propertyControls != null

if (isParsedComponent || hasPropertyControl) {
// Don't add an import if this is from the same file.
const importsToAdd =
originatingPath === fullPath ? emptyImports() : { [fullPath]: importDetailsToAdd }
result.push(exportedComponentDetail(importsToAdd, listingName))
}
}

Expand Down Expand Up @@ -142,13 +156,19 @@ export function getExportedComponentImports(
originatingPath: string,
fullPath: string,
textFile: ParsedTextFile,
propertyControlsInfo: PropertyControlsInfo,
): ExportedComponentImports | null {
return foldParsedTextFile(
() => {
return null
},
(success: ParseSuccess) =>
getExportedComponentImportsFromParseSuccess(originatingPath, fullPath, success),
getExportedComponentImportsFromParseSuccess(
originatingPath,
fullPath,
success,
propertyControlsInfo,
),
() => {
return null
},
Expand Down
3 changes: 2 additions & 1 deletion editor/src/components/shared/project-components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,7 @@ export function getComponentGroups(
originatingPath,
fullPath,
file.fileContents.parsed,
propertyControlsInfo,
)
let insertableComponents: Array<InsertableComponent> = []
fastForEach(possibleExportedComponents, (exportedComponent) => {
Expand All @@ -718,7 +719,7 @@ export function getComponentGroups(
)

// Drill down into the property controls to see if this has an appropriate style object entry.
const stylePropOptions = hasStyleControls(propertyControls)
const stylePropOptions = hasStyleControls(propertyControls ?? {})
? addSizeAndNotStyleProp
: doNotAddStyleProp

Expand Down
9 changes: 6 additions & 3 deletions editor/src/core/property-controls/property-controls-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ export function propertyControlsForComponentInFile(
componentName: string,
filePathNoExtension: string,
propertyControlsInfo: PropertyControlsInfo,
): PropertyControls {
): PropertyControls | null {
const propertyControlsForFile = propertyControlsInfo[filePathNoExtension] ?? {}
const propertyControlsForComponent = propertyControlsForFile[componentName]?.properties
return propertyControlsForComponent ?? {}
const propertyControlsForComponent = propertyControlsForFile[componentName]
if (propertyControlsForComponent == null) {
return null
}
return propertyControlsForComponent.properties
}

export function getPropertyControlsForTargetFromEditor(
Expand Down

0 comments on commit 37f29eb

Please sign in to comment.