Skip to content

Commit

Permalink
feat: Generate view config as .json
Browse files Browse the repository at this point in the history
  • Loading branch information
mrousavy committed Jan 16, 2025
1 parent 8772df9 commit 8e56d0b
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 4 deletions.
6 changes: 5 additions & 1 deletion packages/nitrogen/src/views/CppHybridViewComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { createFileMetadataString, escapeCppName } from '../syntax/helpers.js'
import { NitroConfig } from '../config/NitroConfig.js'
import { getHybridObjectName } from '../syntax/getHybridObjectName.js'
import { includeHeader } from '../syntax/c++/includeNitroHeader.js'
import { createHostComponentJs } from './createHostComponentJs.js'

interface ViewComponentNames {
propsClassName: `${string}Props`
Expand Down Expand Up @@ -232,7 +233,7 @@ namespace ${namespace} {
#endif
`.trim()

return [
const files: SourceFile[] = [
{
name: `${component}.hpp`,
content: componentHeaderCode,
Expand All @@ -248,4 +249,7 @@ namespace ${namespace} {
subdirectory: ['views'],
},
]
const jsFiles = createHostComponentJs(spec)
files.push(...(jsFiles as unknown as SourceFile[]))
return files
}
32 changes: 32 additions & 0 deletions packages/nitrogen/src/views/createHostComponentJs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { Language } from '../getPlatformSpecs.js'
import type { HybridObjectSpec } from '../syntax/HybridObjectSpec.js'
import type { SourceFile } from '../syntax/SourceFile.js'
import { getHybridObjectName } from '../syntax/getHybridObjectName.js'
import { indent } from '../utils.js'

export function createHostComponentJs(spec: HybridObjectSpec): SourceFile[] {
const { T } = getHybridObjectName(spec.name)
const props = spec.properties.map((p) => `"${p.name}": true`)

const code = `
{
"uiViewClassName": "${T}",
"supportsRawText": false,
"bubblingEventTypes": {},
"directEventTypes": {},
"validAttributes": {
${indent(props.join(',\n'), ' ')}
}
}
`.trim()

return [
{
content: code,
language: 'json' as Language,
name: `${T}Config.json`,
platform: 'shared',
subdirectory: [],
},
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ - (instancetype) init {
- (void) updateView {
// 1. Get Swift part
NitroImage::HybridTestViewSpec_cxx& swiftPart = _hybridView->getSwiftPart();

// 2. Get UIView*
void* viewUnsafe = swiftPart.getView();
UIView* view = (__bridge_transfer UIView*) viewUnsafe;

// 3. Update RCTViewComponentView's [contentView]
[self setContentView:view];
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"uiViewClassName": "TestView",
"supportsRawText": false,
"bubblingEventTypes": {},
"directEventTypes": {},
"validAttributes": {
"someProp": true,
"someCallback": true
}
}
7 changes: 7 additions & 0 deletions packages/react-native-nitro-image/src/views/TestView.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { getHostComponent } from 'react-native-nitro-modules'
import TestViewConfig from '../../nitrogen/generated/shared/json/TestViewConfig.json'

/**
* Represents the HybridView `TestView`, which can be rendered as a React Native view.
*/
export const TestView = getHostComponent('TestView', () => TestViewConfig)
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { HostComponent } from 'react-native'
import { Platform, type HostComponent } from 'react-native'
// @ts-expect-error this unfortunately isn't typed or default-exported.
import * as NativeComponentRegistry from 'react-native/Libraries/NativeComponent/NativeComponentRegistry'

interface ViewConfig<Props> {
export interface ViewConfig<Props> {
uiViewClassName: string
supportsRawText?: boolean
bubblingEventTypes: Record<string, unknown>
directEventTypes: Record<string, unknown>
validAttributes: Record<keyof Props, true>
validAttributes: Record<keyof Props, boolean>
}

/**
Expand All @@ -17,5 +17,10 @@ export function getHostComponent<Props>(
name: string,
getViewConfig: () => ViewConfig<Props>
): HostComponent<Props> {
if (NativeComponentRegistry == null) {
throw new Error(
`NativeComponentRegistry is not available on ${Platform.OS}!`
)
}
return NativeComponentRegistry.get<Props>(name, getViewConfig)
}

0 comments on commit 8e56d0b

Please sign in to comment.