react-three-game 0.0.89 → 0.0.91
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/dist/tools/prefabeditor/EditorUI.js +3 -3
- package/dist/tools/prefabeditor/PrefabEditor.js +1 -1
- package/dist/tools/prefabeditor/PrefabRoot.js +4 -2
- package/dist/tools/prefabeditor/components/BufferGeometryComponent.js +3 -14
- package/dist/tools/prefabeditor/components/DataComponent.js +2 -13
- package/dist/tools/prefabeditor/components/Input.js +17 -29
- package/dist/tools/prefabeditor/components/ModelComponent.js +2 -20
- package/dist/tools/prefabeditor/components/PhysicsComponent.d.ts +4 -0
- package/dist/tools/prefabeditor/components/PhysicsComponent.js +91 -22
- package/dist/tools/prefabeditor/components/SoundComponent.js +2 -20
- package/dist/tools/prefabeditor/components/TransformComponent.js +4 -3
- package/dist/tools/prefabeditor/components/lightUtils.js +3 -20
- package/dist/tools/prefabeditor/styles.d.ts +6 -0
- package/dist/tools/prefabeditor/styles.js +70 -57
- package/package.json +1 -1
|
@@ -43,18 +43,18 @@ function NodeInspector({ node, updateNode, deleteNode, basePath }) {
|
|
|
43
43
|
const available = allKeys.filter(k => !hasComponent(node, k));
|
|
44
44
|
const [preferredAddType, setAddType] = useState(available[0] || "");
|
|
45
45
|
const addType = available.includes(preferredAddType) ? preferredAddType : (available[0] || "");
|
|
46
|
-
return _jsxs("div", { style: inspector.content, children: [_jsxs("div", { style: base.section, children: [_jsxs("div", { style: { display: "flex", marginBottom:
|
|
46
|
+
return _jsxs("div", { style: inspector.content, children: [_jsxs("div", { style: base.section, children: [_jsxs("div", { style: { display: "flex", marginBottom: 4, alignItems: 'center', gap: 4 }, children: [_jsx("div", { style: { fontSize: 10, color: colors.textDim, wordBreak: 'break-all', background: colors.bgLight, padding: '2px 4px', flex: 1, fontFamily: 'monospace', minHeight: 18, boxSizing: 'border-box' }, children: node.id }), _jsx("button", { style: Object.assign(Object.assign(Object.assign({}, base.btn), base.btnDanger), { minWidth: 22, padding: '2px 4px' }), title: "Delete Node", onClick: deleteNode, children: "\u2715" })] }), _jsx("input", { style: base.input, value: (_a = node.name) !== null && _a !== void 0 ? _a : "", placeholder: 'Node name', onChange: e => updateNode(n => (Object.assign(Object.assign({}, n), { name: e.target.value }))) })] }), _jsxs("div", { style: base.section, children: [_jsx("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 4 }, children: _jsx("div", { style: base.label, children: "Components" }) }), node.components && Object.entries(node.components).map(([key, comp]) => {
|
|
47
47
|
if (!comp)
|
|
48
48
|
return null;
|
|
49
49
|
const def = ALL_COMPONENTS[comp.type];
|
|
50
50
|
if (!def)
|
|
51
51
|
return _jsxs("div", { style: { color: colors.danger, fontSize: 11 }, children: ["Unknown: ", comp.type] }, key);
|
|
52
|
-
return (_jsxs("div", { style: componentCard.container, children: [_jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom:
|
|
52
|
+
return (_jsxs("div", { style: componentCard.container, children: [_jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 3 }, children: [_jsx("div", { style: { fontSize: 11, fontWeight: 500 }, children: key }), _jsx("button", { style: Object.assign(Object.assign({}, base.btn), { padding: '2px 4px', minWidth: 20 }), title: "Remove Component", onClick: () => updateNode(n => {
|
|
53
53
|
var _a;
|
|
54
54
|
const _b = (_a = n.components) !== null && _a !== void 0 ? _a : {}, _c = key, _ = _b[_c], rest = __rest(_b, [typeof _c === "symbol" ? _c : _c + ""]);
|
|
55
55
|
return Object.assign(Object.assign({}, n), { components: rest });
|
|
56
56
|
}), children: "\u2715" })] }), def.Editor && (_jsx(def.Editor, { component: comp, node: node, onUpdate: (newProps) => updateNode(n => (Object.assign(Object.assign({}, n), { components: Object.assign(Object.assign({}, n.components), { [key]: Object.assign(Object.assign({}, comp), { properties: Object.assign(Object.assign({}, comp.properties), newProps) }) }) }))), basePath: basePath }))] }, key));
|
|
57
|
-
})] }), available.length > 0 && (_jsx("div", { children: _jsxs("div", { style: base.row, children: [_jsx("select", { style: Object.assign(Object.assign({}, base.input), { flex: 1 }), value: addType, onChange: e => setAddType(e.target.value), children: available.map(k => _jsx("option", { value: k, children: k }, k)) }), _jsx("button", { style: base.btn, disabled: !addType, onClick: () => {
|
|
57
|
+
})] }), available.length > 0 && (_jsx("div", { children: _jsxs("div", { style: base.row, children: [_jsx("select", { style: Object.assign(Object.assign({}, base.input), { flex: 1, background: colors.bgInput, border: `1px solid ${colors.border}`, minHeight: 22 }), value: addType, onChange: e => setAddType(e.target.value), children: available.map(k => _jsx("option", { value: k, children: k }, k)) }), _jsx("button", { style: base.btn, disabled: !addType, onClick: () => {
|
|
58
58
|
if (!addType)
|
|
59
59
|
return;
|
|
60
60
|
const def = ALL_COMPONENTS[addType];
|
|
@@ -370,7 +370,7 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, physics = true, mode
|
|
|
370
370
|
}
|
|
371
371
|
(_d = canvasProps === null || canvasProps === void 0 ? void 0 : canvasProps.onPointerMissed) === null || _d === void 0 ? void 0 : _d.call(canvasProps, event);
|
|
372
372
|
}
|
|
373
|
-
: canvasProps === null || canvasProps === void 0 ? void 0 : canvasProps.onPointerMissed, children: [physics ? (_jsx(Physics, { debug: isEditMode, paused: isEditMode, children: content })) : content, isEditMode && (_jsxs(_Fragment, { children: [_jsx(MapControls, { ref: controlsRef, enableDamping: false, makeDefault: true }), transformObject && (_jsx(TransformControls, { object: transformObject, mode: transformMode, space: "local", onObjectChange: handleTransformChange, translationSnap: positionSnap > 0 ? positionSnap : undefined, rotationSnap: rotationSnap > 0 ? rotationSnap : undefined, scaleSnap: scaleSnap > 0 ? scaleSnap : undefined }, `transform-${selectedId}-${transformMode}-${positionSnap}-${rotationSnap}-${scaleSnap}`))] }))] })), showUI && (_jsxs(_Fragment, { children: [_jsxs("div", { style: toolbar.panel, children: [_jsx("button", { style: base.btn, onClick: toggleMode, children: isEditMode ? "▶" : "⏸" }), uiPlugins] }), isEditMode && (_jsx(EditorUI, { selectedId: selectedId, setSelectedId: setSelection, getPrefab: getPrefab, onReplacePrefab: (prefab) => loadPrefab(prefab, { resetHistory: true }), onImportPrefab: importPrefab, basePath: basePath, onUndo: undo, onRedo: redo, canUndo: historyIndex > 0, canRedo: historyIndex < history.length - 1 }))] }))] }) });
|
|
373
|
+
: canvasProps === null || canvasProps === void 0 ? void 0 : canvasProps.onPointerMissed, children: [physics ? (_jsx(Physics, { colliders: false, debug: isEditMode, paused: isEditMode, children: content })) : content, isEditMode && (_jsxs(_Fragment, { children: [_jsx(MapControls, { ref: controlsRef, enableDamping: false, makeDefault: true }), transformObject && (_jsx(TransformControls, { object: transformObject, mode: transformMode, space: "local", onObjectChange: handleTransformChange, translationSnap: positionSnap > 0 ? positionSnap : undefined, rotationSnap: rotationSnap > 0 ? rotationSnap : undefined, scaleSnap: scaleSnap > 0 ? scaleSnap : undefined }, `transform-${selectedId}-${transformMode}-${positionSnap}-${rotationSnap}-${scaleSnap}`))] }))] })), showUI && (_jsxs(_Fragment, { children: [_jsxs("div", { style: toolbar.panel, children: [_jsx("button", { style: base.btn, onClick: toggleMode, children: isEditMode ? "▶" : "⏸" }), uiPlugins] }), isEditMode && (_jsx(EditorUI, { selectedId: selectedId, setSelectedId: setSelection, getPrefab: getPrefab, onReplacePrefab: (prefab) => loadPrefab(prefab, { resetHistory: true }), onImportPrefab: importPrefab, basePath: basePath, onUndo: undo, onRedo: redo, canUndo: historyIndex > 0, canRedo: historyIndex < history.length - 1 }))] }))] }) });
|
|
374
374
|
});
|
|
375
375
|
PrefabEditor.displayName = "PrefabEditor";
|
|
376
376
|
export default PrefabEditor;
|
|
@@ -336,8 +336,10 @@ function StandardNode({ nodeId, selectedId, onSelect, onClick, registerRef, load
|
|
|
336
336
|
const renderCtx = { loadedModels, editMode, registerRef };
|
|
337
337
|
const childNodes = _jsx(ChildNodes, { childIds: childIds, parentMatrix: world, selectedId: selectedId, onSelect: onSelect, onClick: onClick, registerRef: registerRef, loadedModels: loadedModels, editMode: editMode });
|
|
338
338
|
const inner = renderCompositionNode(gameObject, renderCtx, primaryClickHandlers, childNodes);
|
|
339
|
-
const
|
|
340
|
-
|
|
339
|
+
const editAnchor = editMode ? (_jsx("mesh", { visible: false, children: _jsx("boxGeometry", { args: [0.01, 0.01, 0.01] }) })) : null;
|
|
340
|
+
const standardNode = (_jsxs("group", Object.assign({ ref: editMode ? handleEditGroupRef : handleGroupRef }, groupProps, (editMode ? editClickHandlers : undefined), { children: [editAnchor, inner] })));
|
|
341
|
+
const physicsNode = hasPhysics && (physicsDef === null || physicsDef === void 0 ? void 0 : physicsDef.View) ? (_jsx(physicsDef.View, Object.assign({ properties: physics.properties }, transformProps, { children: _jsxs("group", Object.assign({ ref: editMode ? handleEditGroupRef : handleGroupRef }, metadataProps, (editMode ? editClickHandlers : undefined), { children: [editAnchor, inner] })) }), physicsKey)) : null;
|
|
342
|
+
return (_jsx(EntityRuntimeScope, { nodeId: nodeId, editMode: editMode, isSelected: isSelected, children: physicsNode !== null && physicsNode !== void 0 ? physicsNode : standardNode }));
|
|
341
343
|
}
|
|
342
344
|
function isRendererHandledComponent(componentType) {
|
|
343
345
|
return componentType === "Transform"
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { BooleanField, FieldGroup, StringField } from "./Input";
|
|
3
|
+
import { base, ui } from "../styles";
|
|
3
4
|
const DEFAULT_TRIANGLE_POSITIONS = [
|
|
4
5
|
0, 0, 0,
|
|
5
6
|
1, 0, 0,
|
|
@@ -37,7 +38,7 @@ function getIndexArray(indices) {
|
|
|
37
38
|
return maxIndex > 65535 ? new Uint32Array(indices) : new Uint16Array(indices);
|
|
38
39
|
}
|
|
39
40
|
function BufferArrayField({ label, value, fallback, onChange, rows = 4, }) {
|
|
40
|
-
return (_jsxs("label", { style: { display: 'grid', gap: 4 }, children: [_jsx("span", { style: {
|
|
41
|
+
return (_jsxs("label", { style: { display: 'grid', gap: 4 }, children: [_jsx("span", { style: Object.assign(Object.assign({}, base.label), { textTransform: 'uppercase', letterSpacing: '0.05em' }), children: label }), _jsx("textarea", { rows: rows, spellCheck: false, defaultValue: toAttributeText(value, fallback), onBlur: (event) => {
|
|
41
42
|
try {
|
|
42
43
|
onChange(parseArrayInput(event.target.value));
|
|
43
44
|
event.target.setCustomValidity('');
|
|
@@ -46,19 +47,7 @@ function BufferArrayField({ label, value, fallback, onChange, rows = 4, }) {
|
|
|
46
47
|
event.target.setCustomValidity('Expected a JSON array of numbers');
|
|
47
48
|
event.target.reportValidity();
|
|
48
49
|
}
|
|
49
|
-
}, style: {
|
|
50
|
-
width: '100%',
|
|
51
|
-
backgroundColor: '#171717',
|
|
52
|
-
border: '1px solid #333',
|
|
53
|
-
padding: '6px 8px',
|
|
54
|
-
fontSize: '11px',
|
|
55
|
-
color: '#eee',
|
|
56
|
-
fontFamily: 'monospace',
|
|
57
|
-
outline: 'none',
|
|
58
|
-
borderRadius: 3,
|
|
59
|
-
resize: 'vertical',
|
|
60
|
-
boxSizing: 'border-box',
|
|
61
|
-
} })] }));
|
|
50
|
+
}, style: Object.assign(Object.assign({}, ui.monoTextInput), { width: '100%', minHeight: rows * 18, padding: '4px 6px', outline: 'none', resize: 'vertical', boxSizing: 'border-box' }) })] }));
|
|
62
51
|
}
|
|
63
52
|
function BufferGeometryComponentEditor({ component, onUpdate, }) {
|
|
64
53
|
var _a;
|
|
@@ -1,22 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
|
-
import { colors } from "../styles";
|
|
3
|
+
import { colors, ui } from "../styles";
|
|
4
4
|
const RESERVED_USER_DATA_KEYS = new Set([
|
|
5
5
|
'prefabNodeId',
|
|
6
6
|
'prefabNodeName',
|
|
7
7
|
]);
|
|
8
|
-
const inputStyle = {
|
|
9
|
-
width: '100%',
|
|
10
|
-
backgroundColor: colors.bgInput,
|
|
11
|
-
border: `1px solid ${colors.border}`,
|
|
12
|
-
padding: '6px 8px',
|
|
13
|
-
fontSize: '11px',
|
|
14
|
-
color: colors.text,
|
|
15
|
-
fontFamily: 'monospace',
|
|
16
|
-
outline: 'none',
|
|
17
|
-
borderRadius: 3,
|
|
18
|
-
boxSizing: 'border-box',
|
|
19
|
-
};
|
|
8
|
+
const inputStyle = Object.assign(Object.assign({}, ui.monoTextInput), { width: '100%', padding: '4px 6px', fontSize: '11px', outline: 'none', boxSizing: 'border-box' });
|
|
20
9
|
function isRecord(value) {
|
|
21
10
|
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
22
11
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
-
import { colors } from '../styles';
|
|
3
|
+
import { colors, ui } from '../styles';
|
|
4
4
|
import { useOptionalPrefabStoreApi } from '../prefabStore';
|
|
5
5
|
// ============================================================================
|
|
6
6
|
// Shared Styles (derived from shared color tokens)
|
|
@@ -10,13 +10,13 @@ const styles = {
|
|
|
10
10
|
width: '80px',
|
|
11
11
|
backgroundColor: colors.bgInput,
|
|
12
12
|
border: `1px solid ${colors.border}`,
|
|
13
|
-
padding: '
|
|
13
|
+
padding: '2px 4px',
|
|
14
14
|
fontSize: '11px',
|
|
15
15
|
color: colors.text,
|
|
16
16
|
fontFamily: 'monospace',
|
|
17
17
|
outline: 'none',
|
|
18
18
|
textAlign: 'right',
|
|
19
|
-
borderRadius:
|
|
19
|
+
borderRadius: 0,
|
|
20
20
|
},
|
|
21
21
|
label: {
|
|
22
22
|
display: 'block',
|
|
@@ -229,9 +229,9 @@ export function Vector3Input({ label, value, onChange, snap, labelExtra }) {
|
|
|
229
229
|
gap: 4,
|
|
230
230
|
backgroundColor: colors.bgInput,
|
|
231
231
|
border: `1px solid ${colors.border}`,
|
|
232
|
-
borderRadius:
|
|
233
|
-
padding: '4px
|
|
234
|
-
minHeight:
|
|
232
|
+
borderRadius: 0,
|
|
233
|
+
padding: '2px 4px',
|
|
234
|
+
minHeight: 22,
|
|
235
235
|
cursor: 'ew-resize',
|
|
236
236
|
}, onPointerDown: e => startScrub(e, index), onPointerMove: onScrubMove, onPointerUp: endScrub, children: [_jsx("span", { style: {
|
|
237
237
|
fontSize: 11,
|
|
@@ -265,13 +265,13 @@ export function Vector3Input({ label, value, onChange, snap, labelExtra }) {
|
|
|
265
265
|
// ============================================================================
|
|
266
266
|
export function ColorInput({ label, value, onChange }) {
|
|
267
267
|
return (_jsxs("div", { children: [label && _jsx(Label, { children: label }), _jsxs("div", { style: { display: 'flex', gap: 4, justifyContent: 'space-between' }, children: [_jsx("input", { type: "color", style: {
|
|
268
|
-
height:
|
|
268
|
+
height: 22,
|
|
269
269
|
width: 48,
|
|
270
270
|
backgroundColor: colors.bgInput,
|
|
271
271
|
border: `1px solid ${colors.border}`,
|
|
272
|
-
borderRadius:
|
|
272
|
+
borderRadius: 0,
|
|
273
273
|
cursor: 'pointer',
|
|
274
|
-
padding:
|
|
274
|
+
padding: 1,
|
|
275
275
|
flexShrink: 0,
|
|
276
276
|
}, value: value, onChange: e => onChange(e.target.value) }), _jsx("input", { type: "text", style: Object.assign({}, styles.input), value: value, onChange: e => onChange(e.target.value) })] })] }));
|
|
277
277
|
}
|
|
@@ -304,20 +304,20 @@ function SearchSuggestionList({ query, options, onSelect, emptyMessage, }) {
|
|
|
304
304
|
gap: 4,
|
|
305
305
|
maxHeight: 160,
|
|
306
306
|
overflowY: 'auto',
|
|
307
|
-
border:
|
|
308
|
-
borderRadius:
|
|
307
|
+
border: 'none',
|
|
308
|
+
borderRadius: 0,
|
|
309
309
|
background: colors.bgSurface,
|
|
310
|
-
padding:
|
|
310
|
+
padding: 2,
|
|
311
311
|
}, children: filtered.length === 0 ? (_jsx("div", { style: { fontSize: 11, color: colors.textMuted, padding: '4px 6px' }, children: emptyMessage })) : filtered.map(option => (_jsxs("button", { type: "button", onClick: () => onSelect(option.value), style: {
|
|
312
312
|
display: 'flex',
|
|
313
313
|
flexDirection: 'column',
|
|
314
314
|
alignItems: 'flex-start',
|
|
315
315
|
gap: 2,
|
|
316
|
-
border:
|
|
317
|
-
borderRadius:
|
|
318
|
-
background: colors.
|
|
316
|
+
border: 'none',
|
|
317
|
+
borderRadius: 0,
|
|
318
|
+
background: colors.bgSurface,
|
|
319
319
|
color: colors.text,
|
|
320
|
-
padding: '6px
|
|
320
|
+
padding: '4px 6px',
|
|
321
321
|
cursor: 'pointer',
|
|
322
322
|
textAlign: 'left',
|
|
323
323
|
}, children: [_jsx("span", { style: { fontSize: 11, fontWeight: 500 }, children: option.label }), option.description ? (_jsx("span", { style: { fontSize: 10, color: colors.textMuted, fontFamily: 'monospace' }, children: option.description })) : null] }, option.value))) })] }));
|
|
@@ -383,19 +383,7 @@ export function ListEditor({ label, items, renderItem, onAdd, addOptions = [], e
|
|
|
383
383
|
setSelectedAddValue((_b = (_a = addOptions[0]) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : '');
|
|
384
384
|
}
|
|
385
385
|
}, [addOptions, hasAddSelector, selectedAddValue]);
|
|
386
|
-
return (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 8 }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between' }, children: [_jsx(Label, { children: label }), _jsxs("div", { style: { display: 'flex', gap: 6, alignItems: 'center' }, children: [hasAddSelector ? (_jsx("div", { style: { minWidth: 140 }, children: _jsx(SelectInput, { value: resolvedAddValue, onChange: setSelectedAddValue, options: canAdd ? addOptions : [{ value: '', label: 'All items added' }] }) })) : null, _jsx("button", { type: "button", onClick: () => onAdd(resolvedAddValue), disabled: !canAddItem, style: {
|
|
387
|
-
width: 22,
|
|
388
|
-
height: 22,
|
|
389
|
-
borderRadius: 3,
|
|
390
|
-
border: `1px solid ${canAddItem ? colors.accentBorder : colors.border}`,
|
|
391
|
-
background: canAddItem ? colors.accentBg : colors.bgSurface,
|
|
392
|
-
color: canAddItem ? colors.accent : colors.textMuted,
|
|
393
|
-
cursor: canAddItem ? 'pointer' : 'not-allowed',
|
|
394
|
-
fontSize: 14,
|
|
395
|
-
lineHeight: 1,
|
|
396
|
-
padding: 0,
|
|
397
|
-
flexShrink: 0,
|
|
398
|
-
}, title: canAddItem ? addButtonTitle : addDisabledTitle, children: "+" })] })] }), items.length === 0 ? (_jsx("div", { style: { fontSize: 11, color: colors.textMuted }, children: emptyMessage })) : null, items.map(renderItem)] }));
|
|
386
|
+
return (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 8 }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between' }, children: [_jsx(Label, { children: label }), _jsxs("div", { style: { display: 'flex', gap: 6, alignItems: 'center' }, children: [hasAddSelector ? (_jsx("div", { style: { minWidth: 140 }, children: _jsx(SelectInput, { value: resolvedAddValue, onChange: setSelectedAddValue, options: canAdd ? addOptions : [{ value: '', label: 'All items added' }] }) })) : null, _jsx("button", { type: "button", onClick: () => onAdd(resolvedAddValue), disabled: !canAddItem, style: Object.assign(Object.assign({}, ui.compactActionButton), { width: 22, minWidth: 22, height: 22, border: `1px solid ${canAddItem ? colors.accentBorder : colors.border}`, background: canAddItem ? colors.accentBg : colors.bgSurface, color: canAddItem ? colors.accent : colors.textMuted, cursor: canAddItem ? 'pointer' : 'not-allowed', fontSize: 14, lineHeight: 1 }), title: canAddItem ? addButtonTitle : addDisabledTitle, children: "+" })] })] }), items.length === 0 ? (_jsx("div", { style: { fontSize: 11, color: colors.textMuted }, children: emptyMessage })) : null, items.map(renderItem)] }));
|
|
399
387
|
}
|
|
400
388
|
export function NumberField({ name, label, values, onChange, fallback = 0, step, min, max, style, }) {
|
|
401
389
|
var _a;
|
|
@@ -5,7 +5,7 @@ import { BooleanField, FieldGroup, Label, ListEditor, NumberInput, SelectInput,
|
|
|
5
5
|
import { useAssetRuntime } from '../assetRuntime';
|
|
6
6
|
import { EditorContext } from '../PrefabEditor';
|
|
7
7
|
import { getRepeatAxesFromModelProperties, normalizeRepeatAxes } from '../InstanceProvider';
|
|
8
|
-
import { colors } from '../styles';
|
|
8
|
+
import { colors, ui } from '../styles';
|
|
9
9
|
const AXIS_OPTIONS = [
|
|
10
10
|
{ value: 'x', label: 'X' },
|
|
11
11
|
{ value: 'y', label: 'Y' },
|
|
@@ -35,25 +35,7 @@ function RepeatAxisEditor({ axes, onChange, positionSnap, }) {
|
|
|
35
35
|
return (_jsx(ListEditor, { label: "Repeat Axes", items: axes, onAdd: addAxis, addOptions: availableAxisOptions, canAdd: availableAxisOptions.length > 0, emptyMessage: "No repeat axes added.", addButtonTitle: "Add repeat axis", addDisabledTitle: "All axes already in use", renderItem: (axisConfig, index) => {
|
|
36
36
|
const usedByOthers = new Set(axes.filter((_, axisIndex) => axisIndex !== index).map(axis => axis.axis));
|
|
37
37
|
const axisOptions = AXIS_OPTIONS.filter(option => option.value === axisConfig.axis || !usedByOthers.has(option.value));
|
|
38
|
-
return (_jsxs("div", { style: {
|
|
39
|
-
display: 'flex',
|
|
40
|
-
flexDirection: 'column',
|
|
41
|
-
gap: 6,
|
|
42
|
-
padding: 8,
|
|
43
|
-
border: `1px solid ${colors.border}`,
|
|
44
|
-
borderRadius: 4,
|
|
45
|
-
background: colors.bgSurface,
|
|
46
|
-
}, children: [_jsxs("div", { style: { display: 'flex', gap: 6, alignItems: 'end' }, children: [_jsx("div", { style: { flex: 1, minWidth: 0 }, children: _jsx(SelectInput, { label: "Axis", value: axisConfig.axis, onChange: (axis) => updateAxis(index, { axis: axis }), options: axisOptions }) }), _jsx("button", { type: "button", onClick: () => removeAxis(index), style: {
|
|
47
|
-
height: 24,
|
|
48
|
-
width: 28,
|
|
49
|
-
borderRadius: 3,
|
|
50
|
-
border: `1px solid ${colors.border}`,
|
|
51
|
-
background: colors.bgInput,
|
|
52
|
-
color: colors.text,
|
|
53
|
-
cursor: 'pointer',
|
|
54
|
-
padding: 0,
|
|
55
|
-
flexShrink: 0,
|
|
56
|
-
}, title: "Remove repeat axis", children: "\u00D7" })] }), _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 6 }, children: [_jsxs("div", { children: [_jsx(Label, { children: "Count" }), _jsx(NumberInput, { value: axisConfig.count, onChange: (count) => updateAxis(index, { count: Math.max(1, Math.floor(count)) }), step: 1, min: 1, style: { width: '100%', minWidth: 0, boxSizing: 'border-box' } })] }), _jsxs("div", { children: [_jsx(Label, { children: "Offset" }), _jsx(NumberInput, { value: axisConfig.offset, onChange: (offset) => updateAxis(index, { offset: quantize(offset, positionSnap) }), step: positionSnap > 0 ? positionSnap : 0.1, style: { width: '100%', minWidth: 0, boxSizing: 'border-box' } })] })] })] }, `${axisConfig.axis}-${index}`));
|
|
38
|
+
return (_jsxs("div", { style: Object.assign(Object.assign({}, ui.secondaryPanel), { display: 'flex', flexDirection: 'column', gap: 6 }), children: [_jsxs("div", { style: { display: 'flex', gap: 6, alignItems: 'end' }, children: [_jsx("div", { style: { flex: 1, minWidth: 0 }, children: _jsx(SelectInput, { label: "Axis", value: axisConfig.axis, onChange: (axis) => updateAxis(index, { axis: axis }), options: axisOptions }) }), _jsx("button", { type: "button", onClick: () => removeAxis(index), style: Object.assign(Object.assign({}, ui.compactActionButton), { height: 24, background: colors.bgInput }), title: "Remove repeat axis", children: "\u00D7" })] }), _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 6 }, children: [_jsxs("div", { children: [_jsx(Label, { children: "Count" }), _jsx(NumberInput, { value: axisConfig.count, onChange: (count) => updateAxis(index, { count: Math.max(1, Math.floor(count)) }), step: 1, min: 1, style: { width: '100%', minWidth: 0, boxSizing: 'border-box' } })] }), _jsxs("div", { children: [_jsx(Label, { children: "Offset" }), _jsx(NumberInput, { value: axisConfig.offset, onChange: (offset) => updateAxis(index, { offset: quantize(offset, positionSnap) }), step: positionSnap > 0 ? positionSnap : 0.1, style: { width: '100%', minWidth: 0, boxSizing: 'border-box' } })] })] })] }, `${axisConfig.axis}-${index}`));
|
|
57
39
|
} }));
|
|
58
40
|
}
|
|
59
41
|
function ModelComponentEditor({ component, node, onUpdate, basePath = "" }) {
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import type { RigidBodyOptions } from "@react-three/rapier";
|
|
2
2
|
import { Component } from "./ComponentRegistry";
|
|
3
3
|
type PhysicsColliderType = NonNullable<RigidBodyOptions['colliders']> | 'capsule';
|
|
4
|
+
type ManualColliderShape = 'cuboid' | 'ball' | 'capsule';
|
|
4
5
|
export type PhysicsProps = Omit<RigidBodyOptions, 'colliders'> & {
|
|
5
6
|
colliders?: PhysicsColliderType;
|
|
7
|
+
manualColliderShape?: ManualColliderShape;
|
|
6
8
|
activeCollisionTypes?: 'all' | undefined;
|
|
7
9
|
linearVelocity?: [number, number, number];
|
|
8
10
|
angularVelocity?: [number, number, number];
|
|
11
|
+
colliderSize?: [number, number, number];
|
|
12
|
+
colliderRadius?: number;
|
|
9
13
|
capsuleRadius?: number;
|
|
10
14
|
capsuleHalfHeight?: number;
|
|
11
15
|
emitSensorEnterEvent?: boolean;
|
|
@@ -10,20 +10,57 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
12
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
13
|
-
import { CapsuleCollider, RigidBody, useRapier } from "@react-three/rapier";
|
|
13
|
+
import { BallCollider, CapsuleCollider, CuboidCollider, RigidBody, useRapier } from "@react-three/rapier";
|
|
14
14
|
import { useCallback, useEffect, useRef } from 'react';
|
|
15
15
|
import { useAssetRuntime, useEntityRuntime } from "../assetRuntime";
|
|
16
16
|
import { gameEvents, getEntityIdFromRigidBody } from "../GameEvents";
|
|
17
|
-
import { usePrefabNode } from "../prefabStore";
|
|
17
|
+
import { usePrefabNode, usePrefabStore } from "../prefabStore";
|
|
18
18
|
import { BooleanField, FieldGroup, NumberField, SelectField, StringField, Vector3Field } from "./Input";
|
|
19
|
-
import { getNodeUserData } from "../types";
|
|
19
|
+
import { findComponent, getNodeUserData } from "../types";
|
|
20
20
|
import { colors } from "../styles";
|
|
21
21
|
export function isPhysicsProps(v) {
|
|
22
22
|
return (v === null || v === void 0 ? void 0 : v.type) === "fixed" || (v === null || v === void 0 ? void 0 : v.type) === "dynamic" || (v === null || v === void 0 ? void 0 : v.type) === "kinematicPosition" || (v === null || v === void 0 ? void 0 : v.type) === "kinematicVelocity";
|
|
23
23
|
}
|
|
24
24
|
const enabledAxesFallback = [true, true, true];
|
|
25
|
+
const manualColliderShapeFallback = 'cuboid';
|
|
26
|
+
const colliderSizeFallback = [1, 1, 1];
|
|
27
|
+
const colliderRadiusFallback = 0.5;
|
|
25
28
|
const capsuleRadiusFallback = 0.35;
|
|
26
29
|
const capsuleHalfHeightFallback = 0.45;
|
|
30
|
+
function isManualColliderShape(value) {
|
|
31
|
+
return value === 'cuboid' || value === 'ball' || value === 'capsule';
|
|
32
|
+
}
|
|
33
|
+
function hasNodeColliderSource(node) {
|
|
34
|
+
return Boolean(findComponent(node, 'Geometry')
|
|
35
|
+
|| findComponent(node, 'BufferGeometry')
|
|
36
|
+
|| findComponent(node, 'Model'));
|
|
37
|
+
}
|
|
38
|
+
function subtreeHasColliderSource(nodeId, nodesById, childIdsById) {
|
|
39
|
+
var _a;
|
|
40
|
+
if (!nodeId)
|
|
41
|
+
return false;
|
|
42
|
+
const pending = [nodeId];
|
|
43
|
+
while (pending.length > 0) {
|
|
44
|
+
const currentId = pending.pop();
|
|
45
|
+
if (!currentId)
|
|
46
|
+
continue;
|
|
47
|
+
const currentNode = nodesById[currentId];
|
|
48
|
+
if (hasNodeColliderSource(currentNode)) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
pending.push(...((_a = childIdsById[currentId]) !== null && _a !== void 0 ? _a : []));
|
|
52
|
+
}
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
function renderManualCollider({ shape, sensor, colliderSize, colliderRadius, capsuleRadius, capsuleHalfHeight, }) {
|
|
56
|
+
if (shape === 'ball') {
|
|
57
|
+
return _jsx(BallCollider, { args: [colliderRadius], sensor: sensor });
|
|
58
|
+
}
|
|
59
|
+
if (shape === 'capsule') {
|
|
60
|
+
return _jsx(CapsuleCollider, { args: [capsuleHalfHeight, capsuleRadius], sensor: sensor });
|
|
61
|
+
}
|
|
62
|
+
return _jsx(CuboidCollider, { args: colliderSize.map(value => value / 2), sensor: sensor });
|
|
63
|
+
}
|
|
27
64
|
function LockedAxisField({ label, name, values, onChange, }) {
|
|
28
65
|
const enabledAxes = Array.isArray(values[name])
|
|
29
66
|
? values[name]
|
|
@@ -53,10 +90,11 @@ function LockedAxisField({ label, name, values, onChange, }) {
|
|
|
53
90
|
const isLocked = !enabledAxes[index];
|
|
54
91
|
return (_jsx("button", { type: "button", onClick: () => toggleAxisLock(index), style: {
|
|
55
92
|
flex: 1,
|
|
93
|
+
minHeight: 22,
|
|
56
94
|
backgroundColor: isLocked ? colors.dangerBg : colors.bgInput,
|
|
57
95
|
border: `1px solid ${isLocked ? colors.dangerBorder : colors.border}`,
|
|
58
|
-
borderRadius:
|
|
59
|
-
padding: '6px
|
|
96
|
+
borderRadius: 0,
|
|
97
|
+
padding: '2px 6px',
|
|
60
98
|
color: isLocked ? colors.danger : colors.textMuted,
|
|
61
99
|
fontSize: '11px',
|
|
62
100
|
fontFamily: 'monospace',
|
|
@@ -64,19 +102,28 @@ function LockedAxisField({ label, name, values, onChange, }) {
|
|
|
64
102
|
}, children: axisLabel }, axisLabel));
|
|
65
103
|
}) })] }));
|
|
66
104
|
}
|
|
67
|
-
function PhysicsComponentEditor({ component, onUpdate }) {
|
|
105
|
+
function PhysicsComponentEditor({ node, component, onUpdate }) {
|
|
106
|
+
const nodeId = node === null || node === void 0 ? void 0 : node.id;
|
|
107
|
+
const hasAutomaticColliderSource = usePrefabStore(state => subtreeHasColliderSource(nodeId, state.nodesById, state.childIdsById));
|
|
108
|
+
const manualColliderShape = isManualColliderShape(component.properties.manualColliderShape)
|
|
109
|
+
? component.properties.manualColliderShape
|
|
110
|
+
: manualColliderShapeFallback;
|
|
68
111
|
return (_jsxs(FieldGroup, { children: [_jsx(SelectField, { name: "type", label: "Type", values: component.properties, onChange: onUpdate, options: [
|
|
69
112
|
{ value: 'dynamic', label: 'Dynamic' },
|
|
70
113
|
{ value: 'fixed', label: 'Fixed' },
|
|
71
114
|
{ value: 'kinematicPosition', label: 'Kinematic Position' },
|
|
72
115
|
{ value: 'kinematicVelocity', label: 'Kinematic Velocity' },
|
|
73
|
-
] }), _jsx(SelectField, { name: "colliders", label: "Collider", values: component.properties, onChange: onUpdate, options: [
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
116
|
+
] }), hasAutomaticColliderSource ? (_jsxs(_Fragment, { children: [_jsx(SelectField, { name: "colliders", label: "Collider", values: component.properties, onChange: onUpdate, options: [
|
|
117
|
+
{ value: 'hull', label: 'Hull (convex)' },
|
|
118
|
+
{ value: 'trimesh', label: 'Trimesh (exact)' },
|
|
119
|
+
{ value: 'cuboid', label: 'Cuboid (box)' },
|
|
120
|
+
{ value: 'ball', label: 'Ball (sphere)' },
|
|
121
|
+
{ value: 'capsule', label: 'Capsule' },
|
|
122
|
+
] }), component.properties.colliders === 'capsule' ? (_jsxs(_Fragment, { children: [_jsx(NumberField, { name: "capsuleRadius", label: "Capsule Radius", values: component.properties, onChange: onUpdate, fallback: capsuleRadiusFallback, min: 0.01, step: 0.01 }), _jsx(NumberField, { name: "capsuleHalfHeight", label: "Capsule Half Height", values: component.properties, onChange: onUpdate, fallback: capsuleHalfHeightFallback, min: 0.01, step: 0.01 })] })) : null] })) : (_jsxs(_Fragment, { children: [_jsx(SelectField, { name: "manualColliderShape", label: "Shape", values: Object.assign(Object.assign({}, component.properties), { manualColliderShape }), onChange: onUpdate, options: [
|
|
123
|
+
{ value: 'cuboid', label: 'Cuboid (box)' },
|
|
124
|
+
{ value: 'ball', label: 'Ball (sphere)' },
|
|
125
|
+
{ value: 'capsule', label: 'Capsule' },
|
|
126
|
+
] }), manualColliderShape === 'cuboid' ? (_jsx(Vector3Field, { name: "colliderSize", label: "Collider Size", values: component.properties, onChange: onUpdate, fallback: colliderSizeFallback })) : null, manualColliderShape === 'ball' ? (_jsx(NumberField, { name: "colliderRadius", label: "Collider Radius", values: component.properties, onChange: onUpdate, fallback: colliderRadiusFallback, min: 0.01, step: 0.01 })) : null, manualColliderShape === 'capsule' ? (_jsxs(_Fragment, { children: [_jsx(NumberField, { name: "capsuleRadius", label: "Capsule Radius", values: component.properties, onChange: onUpdate, fallback: capsuleRadiusFallback, min: 0.01, step: 0.01 }), _jsx(NumberField, { name: "capsuleHalfHeight", label: "Capsule Half Height", values: component.properties, onChange: onUpdate, fallback: capsuleHalfHeightFallback, min: 0.01, step: 0.01 })] })) : null] })), _jsx(NumberField, { name: "mass", label: "Mass", values: component.properties, onChange: onUpdate, fallback: 1, step: 0.1, min: 0 }), _jsx(NumberField, { name: "restitution", label: "Restitution (Bounciness)", values: component.properties, onChange: onUpdate, fallback: 0, min: 0, max: 1, step: 0.1 }), _jsx(NumberField, { name: "friction", label: "Friction", values: component.properties, onChange: onUpdate, fallback: 0.5, min: 0, step: 0.1 }), _jsx(NumberField, { name: "linearDamping", label: "Linear Damping", values: component.properties, onChange: onUpdate, fallback: 0, min: 0, step: 0.1 }), _jsx(NumberField, { name: "angularDamping", label: "Angular Damping", values: component.properties, onChange: onUpdate, fallback: 0, min: 0, step: 0.1 }), _jsx(NumberField, { name: "gravityScale", label: "Gravity Scale", values: component.properties, onChange: onUpdate, fallback: 1, step: 0.1 }), _jsx(Vector3Field, { name: "linearVelocity", label: "Linear Velocity", values: component.properties, onChange: onUpdate, fallback: [0, 0, 0] }), _jsx(Vector3Field, { name: "angularVelocity", label: "Angular Velocity", values: component.properties, onChange: onUpdate, fallback: [0, 0, 0] }), _jsx(LockedAxisField, { label: "Lock Movement", name: "enabledTranslations", values: component.properties, onChange: onUpdate }), _jsx(LockedAxisField, { label: "Lock Rotations", name: "enabledRotations", values: component.properties, onChange: onUpdate }), _jsx(BooleanField, { name: "sensor", label: "Sensor (Trigger Only)", values: component.properties, onChange: onUpdate, fallback: false }), _jsx(BooleanField, { name: "emitCollisionEnterEvent", label: "Emit Collision Enter", values: component.properties, onChange: onUpdate, fallback: false }), component.properties.emitCollisionEnterEvent ? (_jsx(StringField, { name: "collisionEnterEventName", label: "Collision Enter Event", values: component.properties, onChange: onUpdate, placeholder: "target:hit" })) : null, _jsx(BooleanField, { name: "emitCollisionExitEvent", label: "Emit Collision Exit", values: component.properties, onChange: onUpdate, fallback: false }), component.properties.emitCollisionExitEvent ? (_jsx(StringField, { name: "collisionExitEventName", label: "Collision Exit Event", values: component.properties, onChange: onUpdate, placeholder: "target:reset" })) : null, _jsx(BooleanField, { name: "emitSensorEnterEvent", label: "Emit Sensor Enter", values: component.properties, onChange: onUpdate, fallback: false }), component.properties.emitSensorEnterEvent ? (_jsx(StringField, { name: "sensorEnterEventName", label: "Sensor Enter Event", values: component.properties, onChange: onUpdate, placeholder: "sensor:enter" })) : null, _jsx(BooleanField, { name: "emitSensorExitEvent", label: "Emit Sensor Exit", values: component.properties, onChange: onUpdate, fallback: false }), component.properties.emitSensorExitEvent ? (_jsx(StringField, { name: "sensorExitEventName", label: "Sensor Exit Event", values: component.properties, onChange: onUpdate, placeholder: "sensor:exit" })) : null, _jsx(SelectField, { name: "activeCollisionTypes", label: "Collision Detection", values: component.properties, onChange: onUpdate, options: [
|
|
80
127
|
{ value: '', label: 'Default (Dynamic only)' },
|
|
81
128
|
{ value: 'all', label: 'All (includes kinematic & fixed)' },
|
|
82
129
|
] })] }));
|
|
@@ -86,17 +133,24 @@ function PhysicsComponentView({ properties, children, position, rotation, scale
|
|
|
86
133
|
const { registerRigidBodyRef } = useAssetRuntime();
|
|
87
134
|
const { editMode, nodeId, getObject } = useEntityRuntime();
|
|
88
135
|
const gameObject = usePrefabNode(nodeId);
|
|
136
|
+
const hasAutomaticColliderSource = usePrefabStore(state => subtreeHasColliderSource(nodeId, state.nodesById, state.childIdsById));
|
|
89
137
|
const nodeName = (_b = (_a = gameObject === null || gameObject === void 0 ? void 0 : gameObject.name) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : '';
|
|
90
138
|
const userData = Object.assign(Object.assign({ prefabNodeId: (_c = gameObject === null || gameObject === void 0 ? void 0 : gameObject.id) !== null && _c !== void 0 ? _c : nodeId }, (nodeName ? { prefabNodeName: nodeName } : {})), getNodeUserData(gameObject));
|
|
91
|
-
const { type, colliders, sensor, activeCollisionTypes, linearVelocity = [0, 0, 0], angularVelocity = [0, 0, 0], capsuleRadius = capsuleRadiusFallback, capsuleHalfHeight = capsuleHalfHeightFallback, emitSensorEnterEvent = false, sensorEnterEventName, emitSensorExitEvent = false, sensorExitEventName, emitCollisionEnterEvent = false, collisionEnterEventName, emitCollisionExitEvent = false, collisionExitEventName, enabledTranslations = enabledAxesFallback, enabledRotations = enabledAxesFallback } = properties, otherProps = __rest(properties, ["type", "colliders", "sensor", "activeCollisionTypes", "linearVelocity", "angularVelocity", "capsuleRadius", "capsuleHalfHeight", "emitSensorEnterEvent", "sensorEnterEventName", "emitSensorExitEvent", "sensorExitEventName", "emitCollisionEnterEvent", "collisionEnterEventName", "emitCollisionExitEvent", "collisionExitEventName", "enabledTranslations", "enabledRotations"]);
|
|
139
|
+
const { type, colliders, sensor, manualColliderShape = manualColliderShapeFallback, activeCollisionTypes, linearVelocity = [0, 0, 0], angularVelocity = [0, 0, 0], colliderSize = colliderSizeFallback, colliderRadius = colliderRadiusFallback, capsuleRadius = capsuleRadiusFallback, capsuleHalfHeight = capsuleHalfHeightFallback, emitSensorEnterEvent = false, sensorEnterEventName, emitSensorExitEvent = false, sensorExitEventName, emitCollisionEnterEvent = false, collisionEnterEventName, emitCollisionExitEvent = false, collisionExitEventName, enabledTranslations = enabledAxesFallback, enabledRotations = enabledAxesFallback } = properties, otherProps = __rest(properties, ["type", "colliders", "sensor", "manualColliderShape", "activeCollisionTypes", "linearVelocity", "angularVelocity", "colliderSize", "colliderRadius", "capsuleRadius", "capsuleHalfHeight", "emitSensorEnterEvent", "sensorEnterEventName", "emitSensorExitEvent", "sensorExitEventName", "emitCollisionEnterEvent", "collisionEnterEventName", "emitCollisionExitEvent", "collisionExitEventName", "enabledTranslations", "enabledRotations"]);
|
|
92
140
|
const colliderType = colliders || (type === 'fixed' ? 'trimesh' : 'hull');
|
|
93
|
-
const
|
|
141
|
+
const resolvedManualColliderShape = isManualColliderShape(manualColliderShape)
|
|
142
|
+
? manualColliderShape
|
|
143
|
+
: manualColliderShapeFallback;
|
|
144
|
+
const usesAutomaticColliderSource = hasAutomaticColliderSource && colliderType !== 'capsule';
|
|
145
|
+
const manualColliderShapeToRender = hasAutomaticColliderSource
|
|
146
|
+
? 'capsule'
|
|
147
|
+
: resolvedManualColliderShape;
|
|
94
148
|
const rigidBodyRef = useRef(null);
|
|
95
149
|
const linearVelocityKey = linearVelocity.join(',');
|
|
96
150
|
const angularVelocityKey = angularVelocity.join(',');
|
|
97
151
|
const rbKey = editMode
|
|
98
|
-
? `${type || 'dynamic'}_${colliderType}_${capsuleRadius}_${capsuleHalfHeight}_${position === null || position === void 0 ? void 0 : position.join(',')}_${rotation === null || rotation === void 0 ? void 0 : rotation.join(',')}`
|
|
99
|
-
: `${type || 'dynamic'}_${colliderType}_${capsuleRadius}_${capsuleHalfHeight}`;
|
|
152
|
+
? `${type || 'dynamic'}_${colliderType}_${resolvedManualColliderShape}_${colliderSize.join(',')}_${colliderRadius}_${capsuleRadius}_${capsuleHalfHeight}_${position === null || position === void 0 ? void 0 : position.join(',')}_${rotation === null || rotation === void 0 ? void 0 : rotation.join(',')}`
|
|
153
|
+
: `${type || 'dynamic'}_${colliderType}_${resolvedManualColliderShape}_${colliderSize.join(',')}_${colliderRadius}_${capsuleRadius}_${capsuleHalfHeight}`;
|
|
100
154
|
const handleRigidBodyRef = useCallback((rigidBody) => {
|
|
101
155
|
rigidBodyRef.current = rigidBody;
|
|
102
156
|
if (!nodeId)
|
|
@@ -184,13 +238,25 @@ function PhysicsComponentView({ properties, children, position, rotation, scale
|
|
|
184
238
|
return;
|
|
185
239
|
dispatchPhysicsEvent(collisionExitEventName, payload);
|
|
186
240
|
}, [collisionExitEventName, dispatchPhysicsEvent, emitCollisionExitEvent]);
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
241
|
+
const editModeTransformProps = editMode
|
|
242
|
+
? {
|
|
243
|
+
position,
|
|
244
|
+
rotation,
|
|
245
|
+
scale,
|
|
246
|
+
}
|
|
247
|
+
: undefined;
|
|
248
|
+
const rigidBodyProps = Object.assign({ ref: handleRigidBodyRef, type, colliders: usesAutomaticColliderSource ? colliderType : false, position: editMode ? undefined : position, rotation: editMode ? undefined : rotation, scale: editMode ? undefined : scale, sensor,
|
|
191
249
|
enabledTranslations,
|
|
192
250
|
enabledRotations, name: nodeName, userData: Object.assign({ entityId: nodeId }, userData), onIntersectionEnter: emitSensorEnterEvent ? handleIntersectionEnter : undefined, onIntersectionExit: emitSensorExitEvent ? handleIntersectionExit : undefined, onCollisionEnter: emitCollisionEnterEvent ? handleCollisionEnter : undefined, onCollisionExit: emitCollisionExitEvent ? handleCollisionExit : undefined }, otherProps);
|
|
193
|
-
|
|
251
|
+
const rigidBodyContent = (_jsxs(_Fragment, { children: [!usesAutomaticColliderSource ? renderManualCollider({
|
|
252
|
+
shape: manualColliderShapeToRender,
|
|
253
|
+
sensor,
|
|
254
|
+
colliderSize,
|
|
255
|
+
colliderRadius,
|
|
256
|
+
capsuleRadius,
|
|
257
|
+
capsuleHalfHeight,
|
|
258
|
+
}) : null, children] }));
|
|
259
|
+
return (_jsx(RigidBody, Object.assign({}, rigidBodyProps, { children: editMode ? (_jsx("group", Object.assign({}, editModeTransformProps, { children: rigidBodyContent }))) : rigidBodyContent }), rbKey));
|
|
194
260
|
}
|
|
195
261
|
const PhysicsComponent = {
|
|
196
262
|
name: 'Physics',
|
|
@@ -199,6 +265,9 @@ const PhysicsComponent = {
|
|
|
199
265
|
defaultProperties: {
|
|
200
266
|
type: 'dynamic',
|
|
201
267
|
colliders: 'hull',
|
|
268
|
+
manualColliderShape: manualColliderShapeFallback,
|
|
269
|
+
colliderSize: colliderSizeFallback,
|
|
270
|
+
colliderRadius: colliderRadiusFallback,
|
|
202
271
|
capsuleRadius: capsuleRadiusFallback,
|
|
203
272
|
capsuleHalfHeight: capsuleHalfHeightFallback,
|
|
204
273
|
linearVelocity: [0, 0, 0],
|
|
@@ -5,7 +5,7 @@ import { SoundPicker } from '../../assetviewer/page';
|
|
|
5
5
|
import { useAssetRuntime, useEntityRuntime } from '../assetRuntime';
|
|
6
6
|
import { gameEvents } from '../GameEvents';
|
|
7
7
|
import { BooleanField, FieldGroup, FieldRenderer, ListEditor, NumberField, SelectField, StringField } from './Input';
|
|
8
|
-
import { colors } from '../styles';
|
|
8
|
+
import { colors, ui } from '../styles';
|
|
9
9
|
import { AudioListener } from 'three';
|
|
10
10
|
const CLIP_MODE_OPTIONS = [
|
|
11
11
|
{ value: 'single', label: 'Single Clip' },
|
|
@@ -116,25 +116,7 @@ function SoundComponentEditor({ component, onUpdate, basePath = '' }) {
|
|
|
116
116
|
type: 'select',
|
|
117
117
|
options: CLIP_MODE_OPTIONS.map(option => ({ value: option.value, label: option.label })),
|
|
118
118
|
},
|
|
119
|
-
], values: component.properties, onChange: onUpdate }), _jsx(ListEditor, { label: "Clips", items: clips, onAdd: addClip, emptyMessage: "No clips added.", addButtonTitle: "Add clip", addDisabledTitle: "Add clip", renderItem: (clip, index) => (_jsxs("div", { style: {
|
|
120
|
-
display: 'flex',
|
|
121
|
-
gap: 6,
|
|
122
|
-
alignItems: 'end',
|
|
123
|
-
padding: 8,
|
|
124
|
-
border: `1px solid ${colors.border}`,
|
|
125
|
-
borderRadius: 4,
|
|
126
|
-
background: colors.bgSurface,
|
|
127
|
-
}, children: [_jsx("div", { style: { flex: 1, minWidth: 0 }, children: _jsx(SoundPicker, { value: clip || undefined, onChange: (nextPath) => updateClip(index, nextPath !== null && nextPath !== void 0 ? nextPath : ''), basePath: basePath }) }), _jsx("button", { type: "button", onClick: () => removeClip(index), style: {
|
|
128
|
-
height: 24,
|
|
129
|
-
width: 28,
|
|
130
|
-
borderRadius: 3,
|
|
131
|
-
border: `1px solid ${colors.border}`,
|
|
132
|
-
background: colors.bgInput,
|
|
133
|
-
color: colors.text,
|
|
134
|
-
cursor: 'pointer',
|
|
135
|
-
padding: 0,
|
|
136
|
-
flexShrink: 0,
|
|
137
|
-
}, title: "Remove clip", children: "\u00D7" })] }, `${clip}-${index}`)) }), _jsx(BooleanField, { name: "positional", label: "Positional", values: component.properties, onChange: onUpdate, fallback: false }), positional ? (_jsxs(_Fragment, { children: [_jsx(NumberField, { name: "refDistance", label: "Ref Distance", values: component.properties, onChange: onUpdate, fallback: 1, min: 0.01, step: 0.1 }), _jsx(NumberField, { name: "maxDistance", label: "Max Distance", values: component.properties, onChange: onUpdate, fallback: 24, min: 0.01, step: 0.1 }), _jsx(NumberField, { name: "rolloffFactor", label: "Rolloff", values: component.properties, onChange: onUpdate, fallback: 1, min: 0, step: 0.1 }), _jsx(SelectField, { name: "distanceModel", label: "Distance Model", values: component.properties, onChange: onUpdate, fallback: "inverse", options: [
|
|
119
|
+
], values: component.properties, onChange: onUpdate }), _jsx(ListEditor, { label: "Clips", items: clips, onAdd: addClip, emptyMessage: "No clips added.", addButtonTitle: "Add clip", addDisabledTitle: "Add clip", renderItem: (clip, index) => (_jsxs("div", { style: Object.assign(Object.assign({}, ui.secondaryPanel), { display: 'flex', gap: 6, alignItems: 'end' }), children: [_jsx("div", { style: { flex: 1, minWidth: 0 }, children: _jsx(SoundPicker, { value: clip || undefined, onChange: (nextPath) => updateClip(index, nextPath !== null && nextPath !== void 0 ? nextPath : ''), basePath: basePath }) }), _jsx("button", { type: "button", onClick: () => removeClip(index), style: Object.assign(Object.assign({}, ui.compactActionButton), { height: 24, background: colors.bgInput }), title: "Remove clip", children: "\u00D7" })] }, `${clip}-${index}`)) }), _jsx(BooleanField, { name: "positional", label: "Positional", values: component.properties, onChange: onUpdate, fallback: false }), positional ? (_jsxs(_Fragment, { children: [_jsx(NumberField, { name: "refDistance", label: "Ref Distance", values: component.properties, onChange: onUpdate, fallback: 1, min: 0.01, step: 0.1 }), _jsx(NumberField, { name: "maxDistance", label: "Max Distance", values: component.properties, onChange: onUpdate, fallback: 24, min: 0.01, step: 0.1 }), _jsx(NumberField, { name: "rolloffFactor", label: "Rolloff", values: component.properties, onChange: onUpdate, fallback: 1, min: 0, step: 0.1 }), _jsx(SelectField, { name: "distanceModel", label: "Distance Model", values: component.properties, onChange: onUpdate, fallback: "inverse", options: [
|
|
138
120
|
{ value: 'inverse', label: 'Inverse' },
|
|
139
121
|
{ value: 'linear', label: 'Linear' },
|
|
140
122
|
{ value: 'exponential', label: 'Exponential' },
|
|
@@ -3,15 +3,16 @@ import { Label, Vector3Input } from "./Input";
|
|
|
3
3
|
import { useEditorContext } from "../PrefabEditor";
|
|
4
4
|
import { colors } from "../styles";
|
|
5
5
|
const buttonStyle = {
|
|
6
|
-
padding: '
|
|
6
|
+
padding: '2px 6px',
|
|
7
7
|
background: colors.bgSurface,
|
|
8
8
|
color: colors.text,
|
|
9
9
|
border: `1px solid ${colors.border}`,
|
|
10
|
-
borderRadius:
|
|
10
|
+
borderRadius: 0,
|
|
11
11
|
cursor: 'pointer',
|
|
12
12
|
font: 'inherit',
|
|
13
13
|
fontSize: 11,
|
|
14
14
|
flex: 1,
|
|
15
|
+
minHeight: 22,
|
|
15
16
|
};
|
|
16
17
|
function TransformModeSelector({ transformMode, setTransformMode }) {
|
|
17
18
|
return (_jsxs("div", { style: { marginBottom: 8 }, children: [_jsx(Label, { children: "Transform Mode" }), _jsx("div", { style: { display: 'flex', gap: 6 }, children: ["translate", "rotate", "scale"].map(mode => {
|
|
@@ -29,7 +30,7 @@ const snapLockBtnStyle = {
|
|
|
29
30
|
background: 'none',
|
|
30
31
|
border: 'none',
|
|
31
32
|
cursor: 'pointer',
|
|
32
|
-
padding:
|
|
33
|
+
padding: 0,
|
|
33
34
|
fontSize: 12,
|
|
34
35
|
lineHeight: 1,
|
|
35
36
|
color: colors.textMuted,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from 'react';
|
|
3
|
-
import { colors } from '../styles';
|
|
3
|
+
import { base, colors, ui } from '../styles';
|
|
4
4
|
import { FieldGroup, FieldRow, NumberInput } from './Input';
|
|
5
5
|
export function mergeWithDefaults(defaults, properties) {
|
|
6
6
|
const merged = Object.assign({}, defaults);
|
|
@@ -15,15 +15,7 @@ export function mergeWithDefaults(defaults, properties) {
|
|
|
15
15
|
return merged;
|
|
16
16
|
}
|
|
17
17
|
export function LightSection({ title, children }) {
|
|
18
|
-
return (_jsxs("div", { style: {
|
|
19
|
-
display: 'flex',
|
|
20
|
-
flexDirection: 'column',
|
|
21
|
-
gap: 8,
|
|
22
|
-
padding: '8px 10px',
|
|
23
|
-
border: `1px solid ${colors.border}`,
|
|
24
|
-
borderRadius: 6,
|
|
25
|
-
background: colors.bgSurface,
|
|
26
|
-
}, children: [_jsx("div", { style: {
|
|
18
|
+
return (_jsxs("div", { style: Object.assign(Object.assign({}, ui.secondaryPanel), { display: 'flex', flexDirection: 'column', gap: 8, padding: 6 }), children: [_jsx("div", { style: {
|
|
27
19
|
fontSize: 10,
|
|
28
20
|
textTransform: 'uppercase',
|
|
29
21
|
letterSpacing: '0.08em',
|
|
@@ -51,14 +43,5 @@ export function ShadowBiasField({ name, label, values, onChange, fallback = 0, }
|
|
|
51
43
|
var _a;
|
|
52
44
|
const value = (_a = values[name]) !== null && _a !== void 0 ? _a : fallback;
|
|
53
45
|
const [step, setStep] = useState(() => getBiasStep(value));
|
|
54
|
-
return (_jsx(FieldRow, { label: label, children: _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 6 }, children: [_jsx(NumberInput, { value: value, onChange: nextValue => onChange({ [name]: nextValue }), step: step, min: -0.1, max: 0.1, style: { width: 92 } }), _jsx("select", { value: step.toString(), onChange: event => setStep(Number(event.target.value)), style: {
|
|
55
|
-
width: 78,
|
|
56
|
-
backgroundColor: colors.bgInput,
|
|
57
|
-
border: `1px solid ${colors.border}`,
|
|
58
|
-
color: colors.text,
|
|
59
|
-
borderRadius: 3,
|
|
60
|
-
fontSize: 11,
|
|
61
|
-
padding: '3px 6px',
|
|
62
|
-
fontFamily: 'monospace',
|
|
63
|
-
}, title: "Bias scrub step", children: shadowBiasSteps.map(option => (_jsx("option", { value: option, children: formatBiasStep(option) }, option))) })] }) }));
|
|
46
|
+
return (_jsx(FieldRow, { label: label, children: _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 6 }, children: [_jsx(NumberInput, { value: value, onChange: nextValue => onChange({ [name]: nextValue }), step: step, min: -0.1, max: 0.1, style: { width: 92 } }), _jsx("select", { value: step.toString(), onChange: event => setStep(Number(event.target.value)), style: Object.assign(Object.assign({}, base.input), { width: 78, fontSize: 11, fontFamily: 'monospace' }), title: "Bias scrub step", children: shadowBiasSteps.map(option => (_jsx("option", { value: option, children: formatBiasStep(option) }, option))) })] }) }));
|
|
64
47
|
}
|
|
@@ -34,6 +34,11 @@ interface ToolbarStyles {
|
|
|
34
34
|
interface ComponentCardStyles {
|
|
35
35
|
container: Style;
|
|
36
36
|
}
|
|
37
|
+
interface UtilityStyles {
|
|
38
|
+
secondaryPanel: Style;
|
|
39
|
+
compactActionButton: Style;
|
|
40
|
+
monoTextInput: Style;
|
|
41
|
+
}
|
|
37
42
|
export declare const colors: {
|
|
38
43
|
bg: string;
|
|
39
44
|
bgSurface: string;
|
|
@@ -64,4 +69,5 @@ export declare const tree: TreeStyles;
|
|
|
64
69
|
export declare const menu: MenuStyles;
|
|
65
70
|
export declare const toolbar: ToolbarStyles;
|
|
66
71
|
export declare const componentCard: ComponentCardStyles;
|
|
72
|
+
export declare const ui: UtilityStyles;
|
|
67
73
|
export {};
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
export const colors = {
|
|
2
|
-
bg: '#
|
|
3
|
-
bgSurface: '#
|
|
4
|
-
bgLight: '#
|
|
5
|
-
bgHover: '#
|
|
6
|
-
bgInput: '#
|
|
7
|
-
border: '#
|
|
8
|
-
borderLight: '#
|
|
9
|
-
borderFaint: '#
|
|
10
|
-
text: '#
|
|
11
|
-
textMuted: '#
|
|
12
|
-
textDim: '#
|
|
13
|
-
accent: '#
|
|
14
|
-
accentBg: '
|
|
15
|
-
accentBorder: '
|
|
16
|
-
danger: '#
|
|
17
|
-
dangerBg: '
|
|
18
|
-
dangerBorder: '
|
|
2
|
+
bg: '#f3f3f3',
|
|
3
|
+
bgSurface: '#d7d7d7',
|
|
4
|
+
bgLight: '#fafafa',
|
|
5
|
+
bgHover: '#e6e6e6',
|
|
6
|
+
bgInput: '#f5f5f5',
|
|
7
|
+
border: '#6f6f6f',
|
|
8
|
+
borderLight: '#9a9a9a',
|
|
9
|
+
borderFaint: '#b8b8b8',
|
|
10
|
+
text: '#2f2f2f',
|
|
11
|
+
textMuted: '#5f5f5f',
|
|
12
|
+
textDim: '#7f7f7f',
|
|
13
|
+
accent: '#1e6f89',
|
|
14
|
+
accentBg: '#a9dded',
|
|
15
|
+
accentBorder: '#5e5e5e',
|
|
16
|
+
danger: '#9c3232',
|
|
17
|
+
dangerBg: '#efcaca',
|
|
18
|
+
dangerBorder: '#6f6f6f',
|
|
19
19
|
};
|
|
20
20
|
export const fonts = {
|
|
21
|
-
family: '
|
|
21
|
+
family: 'Tahoma, Verdana, sans-serif',
|
|
22
22
|
size: 11,
|
|
23
23
|
sizeSm: 10,
|
|
24
24
|
};
|
|
@@ -28,44 +28,48 @@ export const base = {
|
|
|
28
28
|
background: colors.bg,
|
|
29
29
|
color: colors.text,
|
|
30
30
|
border: `1px solid ${colors.border}`,
|
|
31
|
-
borderRadius: 4,
|
|
32
31
|
fontFamily: fonts.family,
|
|
33
32
|
fontSize: fonts.size,
|
|
34
|
-
|
|
33
|
+
borderRadius: 0,
|
|
34
|
+
boxShadow: 'none',
|
|
35
35
|
},
|
|
36
36
|
header: {
|
|
37
|
-
padding: '
|
|
37
|
+
padding: '3px 6px',
|
|
38
38
|
display: 'flex',
|
|
39
39
|
alignItems: 'center',
|
|
40
40
|
justifyContent: 'space-between',
|
|
41
41
|
cursor: 'pointer',
|
|
42
42
|
background: colors.bgLight,
|
|
43
|
-
borderBottom: `1px solid ${colors.
|
|
43
|
+
borderBottom: `1px solid ${colors.border}`,
|
|
44
44
|
fontSize: fonts.size,
|
|
45
|
-
fontWeight:
|
|
46
|
-
textTransform: 'uppercase',
|
|
47
|
-
letterSpacing: 0.8,
|
|
45
|
+
fontWeight: 400,
|
|
48
46
|
color: colors.text,
|
|
47
|
+
minHeight: 22,
|
|
48
|
+
boxSizing: 'border-box',
|
|
49
49
|
},
|
|
50
50
|
input: {
|
|
51
51
|
width: '100%',
|
|
52
52
|
background: colors.bgInput,
|
|
53
53
|
border: `1px solid ${colors.border}`,
|
|
54
|
-
borderRadius:
|
|
55
|
-
padding: '
|
|
54
|
+
borderRadius: 0,
|
|
55
|
+
padding: '2px 4px',
|
|
56
56
|
color: colors.text,
|
|
57
57
|
fontSize: fonts.size,
|
|
58
58
|
outline: 'none',
|
|
59
|
+
minHeight: 22,
|
|
60
|
+
boxSizing: 'border-box',
|
|
59
61
|
},
|
|
60
62
|
btn: {
|
|
61
|
-
background: colors.
|
|
63
|
+
background: colors.bgSurface,
|
|
62
64
|
border: `1px solid ${colors.border}`,
|
|
63
|
-
borderRadius:
|
|
64
|
-
padding: '
|
|
65
|
+
borderRadius: 0,
|
|
66
|
+
padding: '2px 6px',
|
|
65
67
|
color: colors.text,
|
|
66
68
|
fontSize: fonts.size,
|
|
67
69
|
cursor: 'pointer',
|
|
68
70
|
outline: 'none',
|
|
71
|
+
minHeight: 22,
|
|
72
|
+
boxSizing: 'border-box',
|
|
69
73
|
},
|
|
70
74
|
btnDanger: {
|
|
71
75
|
background: colors.dangerBg,
|
|
@@ -75,25 +79,22 @@ export const base = {
|
|
|
75
79
|
label: {
|
|
76
80
|
fontSize: fonts.sizeSm,
|
|
77
81
|
color: colors.textMuted,
|
|
78
|
-
marginBottom:
|
|
79
|
-
|
|
80
|
-
letterSpacing: 0.5,
|
|
81
|
-
fontWeight: 500,
|
|
82
|
+
marginBottom: 2,
|
|
83
|
+
fontWeight: 400,
|
|
82
84
|
},
|
|
83
85
|
row: {
|
|
84
86
|
display: 'flex',
|
|
85
|
-
gap:
|
|
87
|
+
gap: 4,
|
|
86
88
|
},
|
|
87
89
|
section: {
|
|
88
|
-
paddingBottom:
|
|
89
|
-
borderBottom: `1px solid ${colors.borderLight}`,
|
|
90
|
+
paddingBottom: 4,
|
|
90
91
|
},
|
|
91
92
|
};
|
|
92
93
|
// Specific panel styles
|
|
93
94
|
export const inspector = {
|
|
94
|
-
panel: Object.assign(Object.assign({}, base.panel), { position: 'absolute', top: 8, right: 8, zIndex: 20, width:
|
|
95
|
+
panel: Object.assign(Object.assign({}, base.panel), { position: 'absolute', top: 8, right: 8, zIndex: 20, width: 300 }),
|
|
95
96
|
content: {
|
|
96
|
-
padding:
|
|
97
|
+
padding: 6,
|
|
97
98
|
maxHeight: '80vh',
|
|
98
99
|
overflowY: 'auto',
|
|
99
100
|
overflowX: 'hidden',
|
|
@@ -102,37 +103,37 @@ export const inspector = {
|
|
|
102
103
|
boxSizing: 'border-box',
|
|
103
104
|
display: 'flex',
|
|
104
105
|
flexDirection: 'column',
|
|
105
|
-
gap:
|
|
106
|
+
gap: 4,
|
|
106
107
|
},
|
|
107
108
|
};
|
|
108
109
|
export const tree = {
|
|
109
110
|
panel: Object.assign(Object.assign({}, base.panel), { maxHeight: '85vh', display: 'flex', flexDirection: 'column', userSelect: 'none' }),
|
|
110
111
|
scroll: {
|
|
111
112
|
overflowY: 'auto',
|
|
112
|
-
padding:
|
|
113
|
+
padding: 2,
|
|
113
114
|
scrollbarWidth: 'thin',
|
|
114
115
|
scrollbarColor: `${colors.bgLight} transparent`,
|
|
115
116
|
},
|
|
116
117
|
row: {
|
|
117
118
|
display: 'flex',
|
|
118
119
|
alignItems: 'center',
|
|
119
|
-
padding: '
|
|
120
|
+
padding: '2px 4px',
|
|
120
121
|
borderBottomWidth: 1,
|
|
121
122
|
borderBottomStyle: 'solid',
|
|
122
123
|
borderBottomColor: colors.borderFaint,
|
|
123
124
|
cursor: 'pointer',
|
|
124
125
|
whiteSpace: 'nowrap',
|
|
125
|
-
borderRadius: 2,
|
|
126
126
|
},
|
|
127
127
|
selected: {
|
|
128
128
|
background: colors.accentBg,
|
|
129
129
|
borderBottomColor: colors.accentBorder,
|
|
130
|
+
boxShadow: 'none',
|
|
130
131
|
},
|
|
131
132
|
iconButton: {
|
|
132
133
|
background: 'none',
|
|
133
134
|
border: 'none',
|
|
134
135
|
cursor: 'pointer',
|
|
135
|
-
padding: '0
|
|
136
|
+
padding: '0 2px',
|
|
136
137
|
fontSize: 14,
|
|
137
138
|
opacity: 0.7,
|
|
138
139
|
color: 'inherit',
|
|
@@ -146,15 +147,15 @@ export const menu = {
|
|
|
146
147
|
width: 'max-content',
|
|
147
148
|
maxWidth: 'min(240px, calc(100vw - 16px))',
|
|
148
149
|
background: colors.bgSurface,
|
|
149
|
-
border:
|
|
150
|
-
borderRadius: 4,
|
|
150
|
+
border: 'none',
|
|
151
151
|
overflow: 'hidden',
|
|
152
|
-
|
|
152
|
+
borderRadius: 0,
|
|
153
|
+
boxShadow: 'none',
|
|
153
154
|
},
|
|
154
155
|
item: {
|
|
155
156
|
width: '100%',
|
|
156
157
|
textAlign: 'left',
|
|
157
|
-
padding: '
|
|
158
|
+
padding: '4px 8px',
|
|
158
159
|
background: 'transparent',
|
|
159
160
|
border: 'none',
|
|
160
161
|
color: colors.text,
|
|
@@ -171,17 +172,17 @@ export const toolbar = {
|
|
|
171
172
|
panel: {
|
|
172
173
|
position: 'absolute',
|
|
173
174
|
top: 8,
|
|
174
|
-
left: '
|
|
175
|
+
left: '232px',
|
|
175
176
|
display: 'flex',
|
|
176
|
-
gap:
|
|
177
|
-
padding: '4px
|
|
177
|
+
gap: 4,
|
|
178
|
+
padding: '2px 4px',
|
|
178
179
|
background: colors.bg,
|
|
179
180
|
border: `1px solid ${colors.border}`,
|
|
180
|
-
borderRadius: 4,
|
|
181
181
|
color: colors.text,
|
|
182
182
|
fontFamily: fonts.family,
|
|
183
183
|
fontSize: fonts.size,
|
|
184
|
-
|
|
184
|
+
borderRadius: 0,
|
|
185
|
+
boxShadow: 'none',
|
|
185
186
|
},
|
|
186
187
|
divider: {
|
|
187
188
|
width: 1,
|
|
@@ -195,10 +196,22 @@ export const toolbar = {
|
|
|
195
196
|
// Reusable component card style for inspector sections
|
|
196
197
|
export const componentCard = {
|
|
197
198
|
container: {
|
|
198
|
-
marginBottom:
|
|
199
|
-
backgroundColor: colors.
|
|
200
|
-
padding:
|
|
201
|
-
|
|
199
|
+
marginBottom: 4,
|
|
200
|
+
backgroundColor: colors.bg,
|
|
201
|
+
padding: 4,
|
|
202
|
+
border: `1px solid ${colors.border}`,
|
|
203
|
+
borderRadius: 0,
|
|
204
|
+
boxShadow: 'none',
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
export const ui = {
|
|
208
|
+
secondaryPanel: {
|
|
209
|
+
background: colors.bgSurface,
|
|
202
210
|
border: `1px solid ${colors.border}`,
|
|
211
|
+
borderRadius: 0,
|
|
212
|
+
padding: 4,
|
|
213
|
+
boxSizing: 'border-box',
|
|
203
214
|
},
|
|
215
|
+
compactActionButton: Object.assign(Object.assign({}, base.btn), { width: 28, minWidth: 28, padding: 0, flexShrink: 0 }),
|
|
216
|
+
monoTextInput: Object.assign(Object.assign({}, base.input), { fontFamily: 'monospace' }),
|
|
204
217
|
};
|