react-three-game 0.0.90 → 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.
@@ -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: 8, alignItems: 'center', gap: 8 }, children: [_jsx("div", { style: { fontSize: 10, color: colors.textDim, wordBreak: 'break-all', border: `1px solid ${colors.border}`, padding: '2px 6px', borderRadius: 3, flex: 1, fontFamily: 'monospace' }, children: node.id }), _jsx("button", { style: Object.assign(Object.assign({}, base.btn), base.btnDanger), title: "Delete Node", onClick: deleteNode, children: "\u274C" })] }), _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: 8 }, children: _jsx("div", { style: base.label, children: "Components" }) }), node.components && Object.entries(node.components).map(([key, comp]) => {
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: 4 }, children: [_jsx("div", { style: { fontSize: 11, fontWeight: 500 }, children: key }), _jsx("button", { style: Object.assign(Object.assign({}, base.btn), { padding: '2px 6px' }), title: "Remove Component", onClick: () => updateNode(n => {
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];
@@ -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 physicsInner = editMode ? _jsx("group", { visible: false, children: inner }) : inner;
340
- return (_jsx(EntityRuntimeScope, { nodeId: nodeId, editMode: editMode, isSelected: isSelected, children: editMode ? (_jsxs(_Fragment, { children: [_jsxs("group", Object.assign({ ref: handleEditGroupRef }, groupProps, editClickHandlers, { children: [_jsx("mesh", { visible: false, children: _jsx("boxGeometry", { args: [0.01, 0.01, 0.01] }) }), inner] })), hasPhysics && (physicsDef === null || physicsDef === void 0 ? void 0 : physicsDef.View) ? (_jsx(physicsDef.View, Object.assign({ properties: physics.properties }, transformProps, { children: physicsInner }), physicsKey)) : null] })) : hasPhysics && (physicsDef === null || physicsDef === void 0 ? void 0 : physicsDef.View) ? (_jsx(physicsDef.View, Object.assign({ properties: physics.properties }, transformProps, { children: _jsx("group", Object.assign({ ref: handleGroupRef }, metadataProps, { children: inner })) }), physicsKey)) : (_jsx("group", Object.assign({ ref: handleGroupRef }, groupProps, { children: inner }))) }));
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: { fontSize: '10px', color: '#888', textTransform: 'uppercase', letterSpacing: '0.05em', fontWeight: 500 }, children: label }), _jsx("textarea", { rows: rows, spellCheck: false, defaultValue: toAttributeText(value, fallback), onBlur: (event) => {
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: '3px 6px',
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: 3,
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: 3,
233
- padding: '4px 6px',
234
- minHeight: 28,
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: 32,
268
+ height: 22,
269
269
  width: 48,
270
270
  backgroundColor: colors.bgInput,
271
271
  border: `1px solid ${colors.border}`,
272
- borderRadius: 3,
272
+ borderRadius: 0,
273
273
  cursor: 'pointer',
274
- padding: 2,
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: `1px solid ${colors.border}`,
308
- borderRadius: 3,
307
+ border: 'none',
308
+ borderRadius: 0,
309
309
  background: colors.bgSurface,
310
- padding: 4,
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: `1px solid ${colors.border}`,
317
- borderRadius: 3,
318
- background: colors.bgInput,
316
+ border: 'none',
317
+ borderRadius: 0,
318
+ background: colors.bgSurface,
319
319
  color: colors.text,
320
- padding: '6px 8px',
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 = "" }) {
@@ -90,10 +90,11 @@ function LockedAxisField({ label, name, values, onChange, }) {
90
90
  const isLocked = !enabledAxes[index];
91
91
  return (_jsx("button", { type: "button", onClick: () => toggleAxisLock(index), style: {
92
92
  flex: 1,
93
+ minHeight: 22,
93
94
  backgroundColor: isLocked ? colors.dangerBg : colors.bgInput,
94
95
  border: `1px solid ${isLocked ? colors.dangerBorder : colors.border}`,
95
- borderRadius: 3,
96
- padding: '6px 8px',
96
+ borderRadius: 0,
97
+ padding: '2px 6px',
97
98
  color: isLocked ? colors.danger : colors.textMuted,
98
99
  fontSize: '11px',
99
100
  fontFamily: 'monospace',
@@ -237,20 +238,25 @@ function PhysicsComponentView({ properties, children, position, rotation, scale
237
238
  return;
238
239
  dispatchPhysicsEvent(collisionExitEventName, payload);
239
240
  }, [collisionExitEventName, dispatchPhysicsEvent, emitCollisionExitEvent]);
240
- const rigidBodyProps = Object.assign({ ref: handleRigidBodyRef, type, colliders: usesAutomaticColliderSource ? colliderType : false, position,
241
- rotation,
242
- scale,
243
- sensor,
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,
244
249
  enabledTranslations,
245
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);
246
- return (_jsxs(RigidBody, Object.assign({}, rigidBodyProps, { children: [!usesAutomaticColliderSource ? renderManualCollider({
251
+ const rigidBodyContent = (_jsxs(_Fragment, { children: [!usesAutomaticColliderSource ? renderManualCollider({
247
252
  shape: manualColliderShapeToRender,
248
253
  sensor,
249
254
  colliderSize,
250
255
  colliderRadius,
251
256
  capsuleRadius,
252
257
  capsuleHalfHeight,
253
- }) : null, children] }), rbKey));
258
+ }) : null, children] }));
259
+ return (_jsx(RigidBody, Object.assign({}, rigidBodyProps, { children: editMode ? (_jsx("group", Object.assign({}, editModeTransformProps, { children: rigidBodyContent }))) : rigidBodyContent }), rbKey));
254
260
  }
255
261
  const PhysicsComponent = {
256
262
  name: 'Physics',
@@ -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: '4px 8px',
6
+ padding: '2px 6px',
7
7
  background: colors.bgSurface,
8
8
  color: colors.text,
9
9
  border: `1px solid ${colors.border}`,
10
- borderRadius: 3,
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: '0 2px',
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: '#1e1e1e',
3
- bgSurface: '#252526',
4
- bgLight: '#2d2d2d',
5
- bgHover: '#2a2d2e',
6
- bgInput: '#1a1a1a',
7
- border: '#3c3c3c',
8
- borderLight: '#333333',
9
- borderFaint: '#2a2a2a',
10
- text: '#cccccc',
11
- textMuted: '#999999',
12
- textDim: '#666666',
13
- accent: '#4c9eff',
14
- accentBg: 'rgba(76, 158, 255, 0.12)',
15
- accentBorder: 'rgba(76, 158, 255, 0.4)',
16
- danger: '#f44747',
17
- dangerBg: 'rgba(244, 71, 71, 0.12)',
18
- dangerBorder: 'rgba(244, 71, 71, 0.35)',
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: 'system-ui, -apple-system, sans-serif',
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
- boxShadow: '0 2px 8px rgba(0,0,0,0.4)',
33
+ borderRadius: 0,
34
+ boxShadow: 'none',
35
35
  },
36
36
  header: {
37
- padding: '7px 10px',
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.borderLight}`,
43
+ borderBottom: `1px solid ${colors.border}`,
44
44
  fontSize: fonts.size,
45
- fontWeight: 600,
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: 3,
55
- padding: '5px 8px',
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.bgLight,
63
+ background: colors.bgSurface,
62
64
  border: `1px solid ${colors.border}`,
63
- borderRadius: 3,
64
- padding: '4px 8px',
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: 4,
79
- textTransform: 'uppercase',
80
- letterSpacing: 0.5,
81
- fontWeight: 500,
82
+ marginBottom: 2,
83
+ fontWeight: 400,
82
84
  },
83
85
  row: {
84
86
  display: 'flex',
85
- gap: 6,
87
+ gap: 4,
86
88
  },
87
89
  section: {
88
- paddingBottom: 8,
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: 260 }),
95
+ panel: Object.assign(Object.assign({}, base.panel), { position: 'absolute', top: 8, right: 8, zIndex: 20, width: 300 }),
95
96
  content: {
96
- padding: 8,
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: 8,
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: 4,
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: '3px 6px',
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 4px',
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: `1px solid ${colors.border}`,
150
- borderRadius: 4,
150
+ border: 'none',
151
151
  overflow: 'hidden',
152
- boxShadow: '0 4px 16px rgba(0,0,0,0.6)',
152
+ borderRadius: 0,
153
+ boxShadow: 'none',
153
154
  },
154
155
  item: {
155
156
  width: '100%',
156
157
  textAlign: 'left',
157
- padding: '7px 12px',
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: '240px',
175
+ left: '232px',
175
176
  display: 'flex',
176
- gap: 6,
177
- padding: '4px 6px',
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
- boxShadow: '0 2px 8px rgba(0,0,0,0.4)',
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: 8,
199
- backgroundColor: colors.bgSurface,
200
- padding: 8,
201
- borderRadius: 4,
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
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-three-game",
3
- "version": "0.0.90",
3
+ "version": "0.0.91",
4
4
  "description": "high performance 3D game engine built in React",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",