Skip to content

Commit

Permalink
Merge pull request #67 from Ledzz/fix/partial-ref-and-docs
Browse files Browse the repository at this point in the history
Fix component ref types and docs
  • Loading branch information
bbohlender authored May 31, 2024
2 parents 5d80ffc + 426e034 commit 232e151
Show file tree
Hide file tree
Showing 13 changed files with 307 additions and 306 deletions.
12 changes: 6 additions & 6 deletions docs/getting-started/components-and-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -344,13 +344,13 @@ The `Input` component extends the `Text` component and allows the user to change

</details>

## SVG
## Svg

The `SVG` component allows rendering an SVG file. The URL of the file is provided in the `src` property. Additionally, the `opacity`, `color`, and `panelMaterialClass` properties can be used to transform the appearance of the SVG, and all the `Container` properties are available for styling the background panel.
The `Svg` component allows rendering an Svg file. The URL of the file is provided in the `src` property. Additionally, the `opacity`, `color`, and `panelMaterialClass` properties can be used to transform the appearance of the Svg, and all the `Container` properties are available for styling the background panel.

```jsx
<Root>
<SVG src="..." width={100} />
<Svg src="..." width={100} />
</Root>
```

Expand All @@ -366,13 +366,13 @@ The `SVG` component allows rendering an SVG file. The URL of the file is provide

</details>

## SVGIconFromText
## Icon

The `SVGIconFromText` component only differs from the `SVG` component in how the SVG content is provided. The `SVGIconFromText` component takes a `text` property, which must contain the source code of the SVG. This component helps to inline small SVG files in use cases such as icons. For example, this component is used to implement the uikit-lucide icon pack. When creating the component, the `svgWidth` and `svgHeight` properties must be provided since three.js currently doesn't respect the viewport defined in svg files.
The `Icon` component only differs from the `SVG` component in how the SVG content is provided. The `Icon` component takes a `text` property, which must contain the source code of the SVG. This component helps to inline small SVG files in use cases such as icons. For example, this component is used to implement the uikit-lucide icon pack. When creating the component, the `svgWidth` and `svgHeight` properties must be provided since three.js currently doesn't respect the viewport defined in svg files.

```jsx
<Root>
<SVGIconFromText text="..." svgWidth={16} svgHeight={16} width={20} />
<Icon text="..." svgWidth={16} svgHeight={16} width={20} />
</Root>
```

Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export type ContainerProperties = {
EventHandlers

export const Container: (
props: ContainerProperties & RefAttributes<ComponentInternals<ContainerProperties>>,
props: ContainerProperties & RefAttributes<ComponentInternals<BaseContainerProperties & EventHandlers>>,
) => ReactNode = forwardRef((properties, ref) => {
const parent = useParent()
const outerRef = useRef<Object3D>(null)
Expand Down
69 changes: 35 additions & 34 deletions packages/react/src/content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,41 +13,42 @@ export type ContentProperties = {
} & BaseContentProperties &
EventHandlers

export const Content: (props: ContentProperties & RefAttributes<ComponentInternals<ContentProperties>>) => ReactNode =
forwardRef((properties, ref) => {
const parent = useParent()
const outerRef = useRef<Object3D>(null)
const innerRef = useRef<Object3D>(null)
const propertySignals = usePropertySignals(properties)
const internals = useMemo(
() =>
createContent(
parent,
propertySignals.style,
propertySignals.properties,
propertySignals.default,
outerRef,
innerRef,
),
[parent, propertySignals],
)
export const Content: (
props: ContentProperties & RefAttributes<ComponentInternals<BaseContentProperties & EventHandlers>>,
) => ReactNode = forwardRef((properties, ref) => {
const parent = useParent()
const outerRef = useRef<Object3D>(null)
const innerRef = useRef<Object3D>(null)
const propertySignals = usePropertySignals(properties)
const internals = useMemo(
() =>
createContent(
parent,
propertySignals.style,
propertySignals.properties,
propertySignals.default,
outerRef,
innerRef,
),
[parent, propertySignals],
)

internals.interactionPanel.name = properties.name ?? ''
internals.interactionPanel.name = properties.name ?? ''

useEffect(() => {
const subscriptions: Subscriptions = []
initialize(internals.initializers, subscriptions)
return () => unsubscribeSubscriptions(subscriptions)
}, [internals])
useEffect(() => {
const subscriptions: Subscriptions = []
initialize(internals.initializers, subscriptions)
return () => unsubscribeSubscriptions(subscriptions)
}, [internals])

useComponentInternals(ref, parent.root.pixelSize, propertySignals.style, internals, internals.interactionPanel)
useComponentInternals(ref, parent.root.pixelSize, propertySignals.style, internals, internals.interactionPanel)

return (
<AddHandlers userHandlers={properties} handlers={internals.handlers} ref={outerRef}>
<primitive object={internals.interactionPanel} />
<object3D matrixAutoUpdate={false} ref={innerRef}>
<ParentProvider value={undefined}>{properties.children}</ParentProvider>
</object3D>
</AddHandlers>
)
})
return (
<AddHandlers userHandlers={properties} handlers={internals.handlers} ref={outerRef}>
<primitive object={internals.interactionPanel} />
<object3D matrixAutoUpdate={false} ref={innerRef}>
<ParentProvider value={undefined}>{properties.children}</ParentProvider>
</object3D>
</AddHandlers>
)
})
2 changes: 1 addition & 1 deletion packages/react/src/custom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export type CustomContainerProperties = {
EventHandlers

export const CustomContainer: (
props: CustomContainerProperties & RefAttributes<ComponentInternals<CustomContainerProperties>>,
props: CustomContainerProperties & RefAttributes<ComponentInternals<BaseCustomContainerProperties & EventHandlers>>,
) => ReactNode = forwardRef((properties, ref) => {
const parent = useParent()
const outerRef = useRef<Object3D>(null)
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/fullscreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export type FullscreenProperties = BaseFullscreenProperties & {
} & EventHandlers

export const Fullscreen: (
props: FullscreenProperties & RefAttributes<ComponentInternals<RootProperties>>,
props: FullscreenProperties & RefAttributes<ComponentInternals<RootProperties & EventHandlers>>,
) => ReactNode = forwardRef((properties, ref) => {
const store = useStore()
const [sizeX, sizeY, pixelSize] = useMemo(() => [signal<number>(1), signal<number>(1), signal<number>(1)], [])
Expand Down
67 changes: 34 additions & 33 deletions packages/react/src/icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,40 +21,41 @@ export type IconProperties = BaseIconProperties &
name?: string
}

export const Icon: (props: IconProperties & RefAttributes<ComponentInternals<IconProperties>>) => ReactNode =
forwardRef((properties, ref) => {
const parent = useParent()
const outerRef = useRef<Object3D>(null)
const propertySignals = usePropertySignals(properties)
const internals = useMemo(
() =>
createIcon(
parent,
properties.text,
properties.svgWidth,
properties.svgHeight,
propertySignals.style,
propertySignals.properties,
propertySignals.default,
outerRef,
),
[parent, properties.svgHeight, properties.svgWidth, properties.text, propertySignals],
)
export const Icon: (
props: IconProperties & RefAttributes<ComponentInternals<Partial<BaseIconProperties & EventHandlers>>>,
) => ReactNode = forwardRef((properties, ref) => {
const parent = useParent()
const outerRef = useRef<Object3D>(null)
const propertySignals = usePropertySignals(properties)
const internals = useMemo(
() =>
createIcon(
parent,
properties.text,
properties.svgWidth,
properties.svgHeight,
propertySignals.style,
propertySignals.properties,
propertySignals.default,
outerRef,
),
[parent, properties.svgHeight, properties.svgWidth, properties.text, propertySignals],
)

internals.interactionPanel.name = properties.name ?? ''
internals.interactionPanel.name = properties.name ?? ''

useEffect(() => {
const subscriptions: Subscriptions = []
initialize(internals.initializers, subscriptions)
return () => unsubscribeSubscriptions(subscriptions)
}, [internals])
useEffect(() => {
const subscriptions: Subscriptions = []
initialize(internals.initializers, subscriptions)
return () => unsubscribeSubscriptions(subscriptions)
}, [internals])

useComponentInternals(ref, parent.root.pixelSize, propertySignals.style, internals, internals.interactionPanel)
useComponentInternals(ref, parent.root.pixelSize, propertySignals.style, internals, internals.interactionPanel)

return (
<AddHandlers userHandlers={properties} ref={outerRef} handlers={internals.handlers}>
<primitive object={internals.interactionPanel} />
<primitive object={internals.iconGroup} />
</AddHandlers>
)
})
return (
<AddHandlers userHandlers={properties} ref={outerRef} handlers={internals.handlers}>
<primitive object={internals.interactionPanel} />
<primitive object={internals.iconGroup} />
</AddHandlers>
)
})
71 changes: 36 additions & 35 deletions packages/react/src/image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,42 +18,43 @@ export type ImageProperties = BaseImageProperties &
name?: string
}

export const Image: (props: ImageProperties & RefAttributes<ComponentInternals<ImageProperties>>) => ReactNode =
forwardRef((properties, ref) => {
const parent = useParent()
const outerRef = useRef<Object3D>(null)
const innerRef = useRef<Object3D>(null)
const propertySignals = usePropertySignals(properties)
const internals = useMemo(
() =>
createImage(
parent,
propertySignals.style,
propertySignals.properties,
propertySignals.default,
outerRef,
innerRef,
),
// eslint-disable-next-line react-hooks/exhaustive-deps
[],
)
export const Image: (
props: ImageProperties & RefAttributes<ComponentInternals<BaseImageProperties & EventHandlers>>,
) => ReactNode = forwardRef((properties, ref) => {
const parent = useParent()
const outerRef = useRef<Object3D>(null)
const innerRef = useRef<Object3D>(null)
const propertySignals = usePropertySignals(properties)
const internals = useMemo(
() =>
createImage(
parent,
propertySignals.style,
propertySignals.properties,
propertySignals.default,
outerRef,
innerRef,
),
// eslint-disable-next-line react-hooks/exhaustive-deps
[],
)

internals.interactionPanel.name = properties.name ?? ''
internals.interactionPanel.name = properties.name ?? ''

useEffect(() => {
const subscriptions: Subscriptions = []
initialize(internals.initializers, subscriptions)
return () => unsubscribeSubscriptions(subscriptions)
}, [internals])
useEffect(() => {
const subscriptions: Subscriptions = []
initialize(internals.initializers, subscriptions)
return () => unsubscribeSubscriptions(subscriptions)
}, [internals])

useComponentInternals(ref, parent.root.pixelSize, propertySignals.style, internals, internals.interactionPanel)
useComponentInternals(ref, parent.root.pixelSize, propertySignals.style, internals, internals.interactionPanel)

return (
<AddHandlers userHandlers={properties} ref={outerRef} handlers={internals.handlers}>
<primitive object={internals.interactionPanel} />
<object3D matrixAutoUpdate={false} ref={innerRef}>
<ParentProvider value={internals}>{properties.children}</ParentProvider>
</object3D>
</AddHandlers>
)
})
return (
<AddHandlers userHandlers={properties} ref={outerRef} handlers={internals.handlers}>
<primitive object={internals.interactionPanel} />
<object3D matrixAutoUpdate={false} ref={innerRef}>
<ParentProvider value={internals}>{properties.children}</ParentProvider>
</object3D>
</AddHandlers>
)
})
2 changes: 1 addition & 1 deletion packages/react/src/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { ComponentInternals, useComponentInternals } from './ref.js'
import { ReadonlySignal, signal } from '@preact/signals-core'
import { useFontFamilies } from './font.js'

export type InputInternals = ComponentInternals<InputProperties> & {
export type InputInternals = ComponentInternals<BaseInputProperties & EventHandlers> & {
current: ReadonlySignal<string>
focus: () => void
}
Expand Down
Loading

0 comments on commit 232e151

Please sign in to comment.