Skip to content

Commit

Permalink
feat: nesting non-container components (Image, SVG, Icon)
Browse files Browse the repository at this point in the history
  • Loading branch information
bbohlender committed Mar 12, 2024
1 parent 853a051 commit d5592f5
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 76 deletions.
17 changes: 16 additions & 1 deletion examples/uikit/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,22 @@ export default function App() {
borderRadius={10}
src="https://picsum.photos/2000/3000"
width={300}
/>
overflow="scroll"
>
<Text backgroundColor="black" padding={10}>
Hello World!
</Text>
<Text backgroundColor="black" padding={10}>
Lorem voluptate aliqua est veniam pariatur enim reprehenderit nisi laboris. Tempor sit magna ea occaecat
velit veniam ipsum do deserunt adipisicing labore. Voluptate consectetur Lorem exercitation laborum do
nulla velit sit. Aliqua sit cupidatat excepteur fugiat. Labore proident ea in in ex ad aute adipisicing
ad in occaecat ullamco tempor pariatur. Excepteur consequat ullamco id est duis elit. Est duis mollit
adipisicing labore fugiat duis elit magna. Deserunt nulla dolore deserunt id sint fugiat cillum
cupidatat nulla dolore veniam anim nulla sunt. Excepteur excepteur nisi officia eiusmod incididunt do.
Id reprehenderit aute nulla dolor ut ex veniam aliqua laboris nisi. Aliqua aute nulla fugiat dolor
voluptate quis. Velit sit aliqua eiusmod irure.
</Text>
</SuspendingImage>
</Suspense>
</DefaultProperties>

Expand Down
6 changes: 4 additions & 2 deletions packages/uikit/src/clipping.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Signal, computed } from '@preact/signals-core'
import { Signal, computed, signal } from '@preact/signals-core'
import { useFrame } from '@react-three/fiber'
import { RefObject, createContext, useContext, useMemo } from 'react'
import { Group, Matrix4, Plane, Vector3 } from 'three'
Expand Down Expand Up @@ -87,7 +87,9 @@ export class ClippingRect {
}
}

const ClippingRectContext = createContext<Signal<ClippingRect | undefined>>(null as any)
const emptySignal = signal(undefined)

const ClippingRectContext = createContext<Signal<ClippingRect | undefined>>(emptySignal)

export const ClippingRectProvider = ClippingRectContext.Provider

Expand Down
40 changes: 8 additions & 32 deletions packages/uikit/src/components/container.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ReactNode, forwardRef, useRef } from 'react'
import { useFlexNode, FlexProvider } from '../flex/react.js'
import { useFlexNode } from '../flex/react.js'
import { WithReactive, createCollection, finalizeCollection } from '../properties/utils.js'
import {
InteractionGroup,
Expand All @@ -12,27 +12,19 @@ import {
import { EventHandlers } from '@react-three/fiber/dist/declarations/src/core/events.js'
import { YogaProperties } from '../flex/node.js'
import { useApplyHoverProperties } from '../hover.js'
import { ClippingRectProvider, useClippingRect, useIsClipped, useParentClippingRect } from '../clipping.js'
import { useIsClipped, useParentClippingRect } from '../clipping.js'
import {
ViewportListeners,
LayoutListeners,
useViewportListeners,
useLayoutListeners,
useGlobalMatrix,
MatrixProvider,
ComponentInternals,
useComponentInternals,
WithConditionals,
ChildrenProvider,
} from './utils.js'
import {
ScrollGroup,
ScrollHandler,
ScrollListeners,
ScrollbarProperties,
useGlobalScrollMatrix,
useScrollPosition,
useScrollbars,
} from '../scroll.js'
import { ScrollHandler, ScrollListeners, ScrollbarProperties, useScrollPosition, useScrollbars } from '../scroll.js'
import {
WithAllAliases,
flexAliasPropertyTransformation,
Expand All @@ -45,7 +37,7 @@ import { WithClasses, useApplyProperties } from '../properties/default.js'
import { useRootGroupRef } from '../utils.js'
import { useApplyResponsiveProperties } from '../responsive.js'
import { Group } from 'three'
import { ElementType, OrderInfoProvider, ZIndexOffset, useOrderInfo } from '../order.js'
import { ElementType, ZIndexOffset, useOrderInfo } from '../order.js'
import { useApplyPreferredColorSchemeProperties } from '../dark.js'
import { useApplyActiveProperties } from '../active.js'

Expand Down Expand Up @@ -92,7 +84,6 @@ export const Container = forwardRef<
)

const scrollPosition = useScrollPosition()
const globalScrollMatrix = useGlobalScrollMatrix(scrollPosition, node, globalMatrix)
useScrollbars(
collection,
scrollPosition,
Expand All @@ -115,15 +106,6 @@ export const Container = forwardRef<
useLayoutListeners(properties, node.size)
useViewportListeners(properties, isClipped)

const clippingRect = useClippingRect(
globalMatrix,
node.size,
node.borderInset,
node.overflow,
node,
parentClippingRect,
)

const rootGroupRef = useRootGroupRef()

const interactionPanel = useInteractionPanel(node.size, node, orderInfo, rootGroupRef)
Expand All @@ -141,15 +123,9 @@ export const Container = forwardRef<
<ScrollHandler listeners={properties} node={node} scrollPosition={scrollPosition}>
<primitive object={interactionPanel} />
</ScrollHandler>
<ScrollGroup node={node} scrollPosition={scrollPosition}>
<MatrixProvider value={globalScrollMatrix}>
<FlexProvider value={node}>
<ClippingRectProvider value={clippingRect}>
<OrderInfoProvider value={orderInfo}>{properties.children}</OrderInfoProvider>
</ClippingRectProvider>
</FlexProvider>
</MatrixProvider>
</ScrollGroup>
<ChildrenProvider globalMatrix={globalMatrix} node={node} orderInfo={orderInfo} scrollPosition={scrollPosition}>
{properties.children}
</ChildrenProvider>
</InteractionGroup>
)
})
28 changes: 24 additions & 4 deletions packages/uikit/src/components/icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { SVGLoader } from 'three/examples/jsm/loaders/SVGLoader.js'
import {
ComponentInternals,
LayoutListeners,
ChildrenProvider,
ViewportListeners,
useComponentInternals,
useGlobalMatrix,
Expand All @@ -34,6 +35,7 @@ import { useApplyResponsiveProperties } from '../responsive.js'
import { ElementType, ZIndexOffset, setupRenderOrder, useOrderInfo } from '../order.js'
import { useApplyPreferredColorSchemeProperties } from '../dark.js'
import { useApplyActiveProperties } from '../active.js'
import { ScrollHandler, ScrollListeners, useScrollPosition, useScrollbars } from '../scroll.js'

const colorHelper = new Color()

Expand All @@ -55,7 +57,8 @@ export const SvgIconFromText = forwardRef<
EventHandlers &
LayoutListeners &
ViewportListeners &
ShadowProperties
ShadowProperties &
ScrollListeners
>((properties, ref) => {
const collection = createCollection()
const groupRef = useRef<Group>(null)
Expand Down Expand Up @@ -141,6 +144,18 @@ export const SvgIconFromText = forwardRef<
})
}, [svgGroup, properties.color, properties.receiveShadow, properties.castShadow])

const scrollPosition = useScrollPosition()
useScrollbars(
collection,
scrollPosition,
node,
globalMatrix,
isClipped,
properties.scrollbarPanelMaterialClass,
parentClippingRect,
orderInfo,
)

//apply all properties
writeCollection(collection, 'width', properties.svgWidth)
writeCollection(collection, 'height', properties.svgHeight)
Expand Down Expand Up @@ -173,7 +188,7 @@ export const SvgIconFromText = forwardRef<

const interactionPanel = useInteractionPanel(node.size, node, backgroundOrderInfo, rootGroupRef)

useComponentInternals(ref, node, interactionPanel)
useComponentInternals(ref, node, interactionPanel, scrollPosition)

return (
<InteractionGroup
Expand All @@ -183,8 +198,13 @@ export const SvgIconFromText = forwardRef<
hoverHandlers={hoverHandlers}
activeHandlers={activeHandlers}
>
<primitive object={interactionPanel} />
<primitive object={svgGroup} />
<ScrollHandler listeners={properties} node={node} scrollPosition={scrollPosition}>
<primitive object={interactionPanel} />
<primitive object={svgGroup} />
</ScrollHandler>
<ChildrenProvider globalMatrix={globalMatrix} node={node} orderInfo={orderInfo} scrollPosition={scrollPosition}>
{properties.children}
</ChildrenProvider>
</InteractionGroup>
)
})
32 changes: 27 additions & 5 deletions packages/uikit/src/components/image.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Group, Mesh, SRGBColorSpace, Texture, TextureLoader, Vector2Tuple } from 'three'
import { forwardRef, useMemo, useRef } from 'react'
import { ReactNode, forwardRef, useMemo, useRef } from 'react'
import { useResourceWithParams, useRootGroupRef, useSignalEffect } from '../utils.js'
import { Signal, computed } from '@preact/signals-core'
import { Inset, YogaProperties } from '../flex/node.js'
Expand All @@ -11,6 +11,7 @@ import { useApplyHoverProperties } from '../hover.js'
import {
ComponentInternals,
LayoutListeners,
ChildrenProvider,
ViewportListeners,
WithConditionals,
useComponentInternals,
Expand Down Expand Up @@ -42,6 +43,7 @@ import { useApplyResponsiveProperties } from '../responsive.js'
import { ElementType, ZIndexOffset, setupRenderOrder, useOrderInfo } from '../order.js'
import { useApplyPreferredColorSchemeProperties } from '../dark.js'
import { useApplyActiveProperties } from '../active.js'
import { ScrollHandler, useScrollPosition, useScrollbars, ScrollbarProperties, ScrollListeners } from '../scroll.js'

export type ImageFit = 'cover' | 'fill'
const FIT_DEFAULT: ImageFit = 'fill'
Expand All @@ -55,7 +57,8 @@ export type ImageProperties = WithConditionals<
opacity?: number
} & TransformProperties &
ImageFitProperties
>
> &
ScrollbarProperties
>
>
>
Expand All @@ -76,13 +79,15 @@ export const Image = forwardRef<
ComponentInternals,
ImageProperties & {
src?: string | Signal<string> | Texture | Signal<Texture | undefined>
children?: ReactNode
materialClass?: MaterialClass
zIndexOffset?: ZIndexOffset
keepAspectRatio?: boolean
} & EventHandlers &
LayoutListeners &
ViewportListeners &
ShadowProperties
ShadowProperties &
ScrollListeners
>((properties, ref) => {
const collection = createCollection()
const texture = useResourceWithParams(loadTexture, properties.src)
Expand Down Expand Up @@ -131,6 +136,18 @@ export const Image = forwardRef<
return result
}, [node, materials, rootGroupRef, parentClippingRect, orderInfo, properties.receiveShadow, properties.castShadow])

const scrollPosition = useScrollPosition()
useScrollbars(
collection,
scrollPosition,
node,
globalMatrix,
isClipped,
properties.scrollbarPanelMaterialClass,
parentClippingRect,
orderInfo,
)

//apply all properties
useApplyProperties(collection, properties)
useApplyPreferredColorSchemeProperties(collection, properties)
Expand Down Expand Up @@ -163,7 +180,7 @@ export const Image = forwardRef<

useSignalEffect(() => void (mesh.visible = !isClipped.value), [mesh, isClipped])

useComponentInternals(ref, node, mesh)
useComponentInternals(ref, node, mesh, scrollPosition)

return (
<InteractionGroup
Expand All @@ -173,7 +190,12 @@ export const Image = forwardRef<
matrix={transformMatrix}
activeHandlers={activeHandlers}
>
<primitive object={mesh} />
<ScrollHandler listeners={properties} node={node} scrollPosition={scrollPosition}>
<primitive object={mesh} />
</ScrollHandler>
<ChildrenProvider globalMatrix={globalMatrix} node={node} orderInfo={orderInfo} scrollPosition={scrollPosition}>
{properties.children}
</ChildrenProvider>
</InteractionGroup>
)
})
Expand Down
40 changes: 14 additions & 26 deletions packages/uikit/src/components/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
usePanelGroupDependencies,
} from '../panel/react.js'
import { WithReactive, createCollection, finalizeCollection, writeCollection } from '../properties/utils.js'
import { FlexProvider, useDeferredRequestLayoutCalculation } from '../flex/react.js'
import { useDeferredRequestLayoutCalculation } from '../flex/react.js'
import { EventHandlers } from '@react-three/fiber/dist/declarations/src/core/events.js'
import { ReadonlySignal, Signal, computed } from '@preact/signals-core'
import { Group, Matrix4, Plane, Vector2Tuple, Vector3 } from 'three'
Expand All @@ -21,21 +21,12 @@ import { useApplyHoverProperties } from '../hover.js'
import {
LayoutListeners,
useLayoutListeners,
MatrixProvider,
ComponentInternals,
useComponentInternals,
WithConditionals,
ChildrenProvider,
} from './utils.js'
import { ClippingRectProvider, useClippingRect } from '../clipping.js'
import {
ScrollGroup,
ScrollHandler,
ScrollListeners,
ScrollbarProperties,
useGlobalScrollMatrix,
useScrollPosition,
useScrollbars,
} from '../scroll.js'
import { ScrollHandler, ScrollListeners, ScrollbarProperties, useScrollPosition, useScrollbars } from '../scroll.js'
import {
WithAllAliases,
flexAliasPropertyTransformation,
Expand All @@ -47,7 +38,7 @@ import { WithClasses, useApplyProperties } from '../properties/default.js'
import { InstancedGlyphProvider, useGetInstancedGlyphGroup } from '../text/react.js'
import { PanelProperties } from '../panel/instanced-panel.js'
import { RootSizeProvider, useApplyResponsiveProperties } from '../responsive.js'
import { ElementType, OrderInfoProvider, patchRenderOrder, useOrderInfo } from '../order.js'
import { ElementType, patchRenderOrder, useOrderInfo } from '../order.js'
import { useApplyPreferredColorSchemeProperties } from '../dark.js'
import { useApplyActiveProperties } from '../active.js'

Expand Down Expand Up @@ -123,7 +114,6 @@ export const Root = forwardRef<

const rootMatrix = useRootMatrix(transformMatrix, node.size, pixelSize, properties)
const scrollPosition = useScrollPosition()
const globalScrollMatrix = useGlobalScrollMatrix(scrollPosition, node, rootMatrix)
useScrollbars(
collection,
scrollPosition,
Expand Down Expand Up @@ -160,7 +150,6 @@ export const Root = forwardRef<
writeCollection(collection, 'height', useDivide(sizeY, pixelSize))
finalizeCollection(collection)

const clippingRect = useClippingRect(rootMatrix, node.size, node.borderInset, node.overflow, node, undefined)
useLayoutListeners(properties, node.size)

const internactionPanel = useInteractionPanel(node.size, node, orderInfo, groupRef)
Expand Down Expand Up @@ -191,17 +180,16 @@ export const Root = forwardRef<
<ScrollHandler node={node} scrollPosition={scrollPosition} listeners={properties}>
<primitive object={internactionPanel} />
</ScrollHandler>
<ScrollGroup node={node} scrollPosition={scrollPosition}>
<MatrixProvider value={globalScrollMatrix}>
<FlexProvider value={node}>
<ClippingRectProvider value={clippingRect}>
<OrderInfoProvider value={orderInfo}>
<RootSizeProvider value={node.size}>{properties.children}</RootSizeProvider>
</OrderInfoProvider>
</ClippingRectProvider>
</FlexProvider>
</MatrixProvider>
</ScrollGroup>
<RootSizeProvider value={node.size}>
<ChildrenProvider
globalMatrix={rootMatrix}
node={node}
orderInfo={orderInfo}
scrollPosition={scrollPosition}
>
{properties.children}
</ChildrenProvider>
</RootSizeProvider>
</InstancedPanelProvider>
</InstancedGlyphProvider>
</RootGroupProvider>
Expand Down
Loading

0 comments on commit d5592f5

Please sign in to comment.