onejs-react 0.1.15 → 0.1.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/components.tsx +54 -1
- package/src/host-config.ts +57 -0
- package/src/index.ts +7 -0
- package/src/types.ts +18 -0
package/package.json
CHANGED
package/src/components.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { forwardRef, useMemo, type ReactElement, type Ref } from 'react';
|
|
1
|
+
import { forwardRef, createElement, useMemo, type ReactElement, type Ref } from 'react';
|
|
2
2
|
import type {
|
|
3
|
+
BaseProps,
|
|
3
4
|
ViewProps,
|
|
4
5
|
TextProps,
|
|
5
6
|
LabelProps,
|
|
@@ -10,6 +11,8 @@ import type {
|
|
|
10
11
|
ScrollViewProps,
|
|
11
12
|
ImageProps,
|
|
12
13
|
ListViewProps,
|
|
14
|
+
FrostedGlassProps,
|
|
15
|
+
FrostedGlassIntrinsicProps,
|
|
13
16
|
VisualElement,
|
|
14
17
|
TextElement,
|
|
15
18
|
LabelElement,
|
|
@@ -19,6 +22,7 @@ import type {
|
|
|
19
22
|
SliderElement,
|
|
20
23
|
ScrollViewElement,
|
|
21
24
|
ImageElement,
|
|
25
|
+
FrostedGlassElement,
|
|
22
26
|
} from './types';
|
|
23
27
|
|
|
24
28
|
declare const CS: any
|
|
@@ -94,6 +98,7 @@ declare module 'react/jsx-runtime' {
|
|
|
94
98
|
'ojs-scrollview': WithRef<ScrollViewProps, ScrollViewElement>;
|
|
95
99
|
'ojs-image': WithRef<ImageProps, ImageElement>;
|
|
96
100
|
'ojs-listview': WithRef<ListViewProps, VisualElement>;
|
|
101
|
+
'ojs-frostedglass': WithRef<FrostedGlassIntrinsicProps, FrostedGlassElement>;
|
|
97
102
|
}
|
|
98
103
|
}
|
|
99
104
|
}
|
|
@@ -112,6 +117,7 @@ declare module 'react' {
|
|
|
112
117
|
'ojs-scrollview': WithRef<ScrollViewProps, ScrollViewElement>;
|
|
113
118
|
'ojs-image': WithRef<ImageProps, ImageElement>;
|
|
114
119
|
'ojs-listview': WithRef<ListViewProps, VisualElement>;
|
|
120
|
+
'ojs-frostedglass': WithRef<FrostedGlassIntrinsicProps, FrostedGlassElement>;
|
|
115
121
|
}
|
|
116
122
|
}
|
|
117
123
|
}
|
|
@@ -172,3 +178,50 @@ export const ListView = forwardRef<VisualElement, ListViewProps>((props, ref) =>
|
|
|
172
178
|
return <ojs-listview ref={ref} {...props} />;
|
|
173
179
|
});
|
|
174
180
|
ListView.displayName = 'ListView';
|
|
181
|
+
|
|
182
|
+
export const FrostedGlass = forwardRef<FrostedGlassElement, FrostedGlassProps>(({ blur, tint, ...rest }, ref) => {
|
|
183
|
+
const parsedTint = useMemo(() => {
|
|
184
|
+
if (!tint) return new CS.UnityEngine.Color(1, 1, 1, 0.15)
|
|
185
|
+
const m = tint.match(/rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*(?:,\s*([\d.]+))?\s*\)/)
|
|
186
|
+
if (m) return new CS.UnityEngine.Color(+m[1] / 255, +m[2] / 255, +m[3] / 255, m[4] != null ? +m[4] : 1)
|
|
187
|
+
return new CS.UnityEngine.Color(1, 1, 1, 0.15)
|
|
188
|
+
}, [tint])
|
|
189
|
+
return <ojs-frostedglass ref={ref} blurRadius={blur ?? 10} tintColor={parsedTint} {...rest} />;
|
|
190
|
+
});
|
|
191
|
+
FrostedGlass.displayName = 'FrostedGlass';
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Create a typed React component for a registered custom element.
|
|
195
|
+
* Use with `registerElement()` to add custom C# VisualElement types to React.
|
|
196
|
+
*
|
|
197
|
+
* @param name - Element name matching what was passed to registerElement()
|
|
198
|
+
* @param displayName - Optional display name for React DevTools
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* import { registerElement, createComponent } from "onejs-react"
|
|
202
|
+
* import { BaseProps, VisualElement } from "onejs-react"
|
|
203
|
+
*
|
|
204
|
+
* // Define props for your custom element
|
|
205
|
+
* interface RadialProgressProps extends BaseProps {
|
|
206
|
+
* progress?: number
|
|
207
|
+
* trackColor?: string
|
|
208
|
+
* }
|
|
209
|
+
*
|
|
210
|
+
* // Register and create the component
|
|
211
|
+
* registerElement("radial-progress", CS.MyGame.UI.RadialProgress)
|
|
212
|
+
* export const RadialProgress = createComponent<RadialProgressProps>("radial-progress")
|
|
213
|
+
*
|
|
214
|
+
* // Use in JSX like any React component
|
|
215
|
+
* <RadialProgress progress={0.75} trackColor="#333" style={{ width: 100, height: 100 }} />
|
|
216
|
+
*/
|
|
217
|
+
export function createComponent<P extends BaseProps = BaseProps>(
|
|
218
|
+
name: string,
|
|
219
|
+
displayName?: string
|
|
220
|
+
) {
|
|
221
|
+
const type = name.startsWith('ojs-') ? name : `ojs-${name}`;
|
|
222
|
+
const Component = forwardRef<VisualElement, P>((props, ref) => {
|
|
223
|
+
return createElement(type, { ...props, ref });
|
|
224
|
+
});
|
|
225
|
+
Component.displayName = displayName || name;
|
|
226
|
+
return Component;
|
|
227
|
+
}
|
package/src/host-config.ts
CHANGED
|
@@ -60,6 +60,7 @@ declare const CS: {
|
|
|
60
60
|
};
|
|
61
61
|
ScaleMode: CSEnum;
|
|
62
62
|
Rect: new (...args: any[]) => any;
|
|
63
|
+
Color: new (r: number, g: number, b: number, a: number) => any;
|
|
63
64
|
};
|
|
64
65
|
OneJS: {
|
|
65
66
|
GPU: {
|
|
@@ -68,6 +69,7 @@ declare const CS: {
|
|
|
68
69
|
SetElementBackgroundFromObject: (element: CSObject, obj: CSObject) => void;
|
|
69
70
|
ClearElementBackgroundImage: (element: CSObject) => void;
|
|
70
71
|
};
|
|
72
|
+
FrostedGlassElement: new () => CSObject;
|
|
71
73
|
};
|
|
72
74
|
};
|
|
73
75
|
};
|
|
@@ -173,8 +175,38 @@ const TYPE_MAP: Record<string, () => CSObject> = {
|
|
|
173
175
|
'ojs-scrollview': () => new CS.UnityEngine.UIElements.ScrollView(),
|
|
174
176
|
'ojs-image': () => new CS.UnityEngine.UIElements.Image(),
|
|
175
177
|
'ojs-listview': () => new CS.UnityEngine.UIElements.ListView(),
|
|
178
|
+
'ojs-frostedglass': () => new CS.OneJS.GPU.FrostedGlassElement(),
|
|
176
179
|
};
|
|
177
180
|
|
|
181
|
+
// Built-in types with specific prop handling in applyComponentProps
|
|
182
|
+
const BUILT_IN_TYPES = new Set(Object.keys(TYPE_MAP));
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Register a custom VisualElement type for use in React JSX.
|
|
186
|
+
*
|
|
187
|
+
* @param name - Element name (with or without 'ojs-' prefix)
|
|
188
|
+
* @param constructor - C# constructor reference (e.g., CS.MyNamespace.MyWidget)
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* import { registerElement, createComponent } from "onejs-react"
|
|
192
|
+
*
|
|
193
|
+
* // Register the custom element
|
|
194
|
+
* registerElement("radial-progress", CS.MyGame.UI.RadialProgress)
|
|
195
|
+
*
|
|
196
|
+
* // Create a typed React component for it
|
|
197
|
+
* const RadialProgress = createComponent<RadialProgressProps>("radial-progress")
|
|
198
|
+
*
|
|
199
|
+
* // Use in JSX
|
|
200
|
+
* <RadialProgress progress={0.75} />
|
|
201
|
+
*/
|
|
202
|
+
export function registerElement(name: string, constructor: new (...args: any[]) => any): void {
|
|
203
|
+
const key = name.startsWith('ojs-') ? name : `ojs-${name}`;
|
|
204
|
+
if (TYPE_MAP[key]) {
|
|
205
|
+
console.error(`registerElement: "${name}" is already registered. Overwriting.`);
|
|
206
|
+
}
|
|
207
|
+
TYPE_MAP[key] = () => new constructor();
|
|
208
|
+
}
|
|
209
|
+
|
|
178
210
|
// Event prop to event type mapping
|
|
179
211
|
const EVENT_PROPS: Record<string, string> = {
|
|
180
212
|
// Click
|
|
@@ -728,8 +760,29 @@ function applyListViewProps(element: CSListView, props: Record<string, unknown>)
|
|
|
728
760
|
setEnumProp(element, 'showAlternatingRowBackgrounds', props, 'showAlternatingRowBackgrounds', UIE.AlternatingRowBackground);
|
|
729
761
|
}
|
|
730
762
|
|
|
763
|
+
// Props handled by the reconciler infrastructure - not forwarded to C# elements
|
|
764
|
+
const RESERVED_PROPS = new Set([
|
|
765
|
+
'children', 'key', 'ref', 'style', 'className', 'pickingMode',
|
|
766
|
+
'onGenerateVisualContent',
|
|
767
|
+
...Object.keys(EVENT_PROPS),
|
|
768
|
+
]);
|
|
769
|
+
|
|
770
|
+
// Forward non-reserved props directly to C# element (for custom elements)
|
|
771
|
+
function applyCustomProps(element: CSObject, props: Record<string, unknown>) {
|
|
772
|
+
for (const [key, value] of Object.entries(props)) {
|
|
773
|
+
if (value === undefined || RESERVED_PROPS.has(key)) continue;
|
|
774
|
+
(element as any)[key] = value;
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
|
|
731
778
|
// Apply component-specific props based on element type
|
|
732
779
|
function applyComponentProps(element: CSObject, type: string, props: Record<string, unknown>) {
|
|
780
|
+
// Custom elements: forward all non-reserved props directly to C# element
|
|
781
|
+
if (!BUILT_IN_TYPES.has(type)) {
|
|
782
|
+
applyCustomProps(element, props);
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
|
|
733
786
|
// For Slider, apply range props (lowValue/highValue) BEFORE value
|
|
734
787
|
// Unity's Slider clamps value to [lowValue, highValue], so range must be set first
|
|
735
788
|
if (type === 'ojs-slider') {
|
|
@@ -750,6 +803,10 @@ function applyComponentProps(element: CSObject, type: string, props: Record<stri
|
|
|
750
803
|
applyScrollViewProps(element as CSScrollView, props);
|
|
751
804
|
} else if (type === 'ojs-listview') {
|
|
752
805
|
applyListViewProps(element as CSListView, props);
|
|
806
|
+
} else if (type === 'ojs-frostedglass') {
|
|
807
|
+
const el = element as any;
|
|
808
|
+
if (props.blurRadius !== undefined) el.BlurRadius = props.blurRadius;
|
|
809
|
+
if (props.tintColor !== undefined) el.TintColor = props.tintColor;
|
|
753
810
|
}
|
|
754
811
|
}
|
|
755
812
|
|
package/src/index.ts
CHANGED
|
@@ -10,9 +10,14 @@ export {
|
|
|
10
10
|
ScrollView,
|
|
11
11
|
Image,
|
|
12
12
|
ListView,
|
|
13
|
+
FrostedGlass,
|
|
13
14
|
clearImageCache,
|
|
15
|
+
createComponent,
|
|
14
16
|
} from './components';
|
|
15
17
|
|
|
18
|
+
// Custom Element Registration
|
|
19
|
+
export { registerElement } from './host-config';
|
|
20
|
+
|
|
16
21
|
// Renderer
|
|
17
22
|
export { render, unmount, flushSync, batchedUpdates, getDebugInfo } from './renderer';
|
|
18
23
|
|
|
@@ -79,6 +84,7 @@ export type {
|
|
|
79
84
|
ScrollViewProps,
|
|
80
85
|
ImageProps,
|
|
81
86
|
ListViewProps,
|
|
87
|
+
FrostedGlassProps,
|
|
82
88
|
// Container type for render()
|
|
83
89
|
RenderContainer,
|
|
84
90
|
// Element types for refs
|
|
@@ -91,6 +97,7 @@ export type {
|
|
|
91
97
|
SliderElement,
|
|
92
98
|
ScrollViewElement,
|
|
93
99
|
ImageElement,
|
|
100
|
+
FrostedGlassElement,
|
|
94
101
|
// Vector drawing types
|
|
95
102
|
Vector2,
|
|
96
103
|
Color,
|
package/src/types.ts
CHANGED
|
@@ -674,6 +674,24 @@ export interface ImageElement extends VisualElement {
|
|
|
674
674
|
|
|
675
675
|
// ListView uses Unity's virtualization callbacks directly
|
|
676
676
|
// This is intentionally imperative - ListView manages its own element recycling
|
|
677
|
+
export interface FrostedGlassProps extends BaseProps {
|
|
678
|
+
/** Blur radius in screen pixels. Higher = more blurry. Default: 10. */
|
|
679
|
+
blur?: number;
|
|
680
|
+
/** Tint color overlaid on the blurred background (CSS color string). */
|
|
681
|
+
tint?: string;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/** Internal props for the ojs-frostedglass intrinsic element */
|
|
685
|
+
export interface FrostedGlassIntrinsicProps extends BaseProps {
|
|
686
|
+
blurRadius?: number;
|
|
687
|
+
tintColor?: any;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
export interface FrostedGlassElement extends VisualElement {
|
|
691
|
+
blurRadius: number;
|
|
692
|
+
tintColor: any;
|
|
693
|
+
}
|
|
694
|
+
|
|
677
695
|
export interface ListViewProps extends BaseProps {
|
|
678
696
|
// Data source - the array of items to display
|
|
679
697
|
itemsSource: unknown[];
|