Refactor brush and model instance selection handling in App.tsx
This commit is contained in:
270
src/app/App.tsx
270
src/app/App.tsx
@@ -4203,6 +4203,7 @@ export function App({ store, initialStatusMessage }: AppProps) {
|
|||||||
<div className="outliner-list" data-testid="outliner-brush-list">
|
<div className="outliner-list" data-testid="outliner-brush-list">
|
||||||
{brushList.map((brush, brushIndex) => {
|
{brushList.map((brush, brushIndex) => {
|
||||||
const label = getBrushLabel(brush, brushIndex);
|
const label = getBrushLabel(brush, brushIndex);
|
||||||
|
const isSelected = selectedBrush?.id === brush.id;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -4210,25 +4211,43 @@ export function App({ store, initialStatusMessage }: AppProps) {
|
|||||||
className={`outliner-item outliner-item--compact ${isBrushSelected(editorState.selection, brush.id) ? "outliner-item--selected" : ""}`}
|
className={`outliner-item outliner-item--compact ${isBrushSelected(editorState.selection, brush.id) ? "outliner-item--selected" : ""}`}
|
||||||
>
|
>
|
||||||
<div className="outliner-item__row">
|
<div className="outliner-item__row">
|
||||||
<button
|
{isSelected ? (
|
||||||
className="outliner-item__select"
|
<input
|
||||||
type="button"
|
className="outliner-item__rename"
|
||||||
data-testid={`outliner-brush-${brush.id}`}
|
data-testid="selected-brush-name"
|
||||||
onClick={() =>
|
type="text"
|
||||||
applySelection(
|
value={brushNameDraft}
|
||||||
{
|
placeholder={`Box Brush ${brushIndex + 1}`}
|
||||||
kind: "brushes",
|
onChange={(event) => setBrushNameDraft(event.currentTarget.value)}
|
||||||
ids: [brush.id]
|
onBlur={applyBrushNameChange}
|
||||||
},
|
onFocus={(event) => event.currentTarget.select()}
|
||||||
"outliner",
|
onKeyDown={(event) =>
|
||||||
{
|
handleInlineNameInputKeyDown(event, () => {
|
||||||
focusViewport: true
|
setBrushNameDraft(selectedBrush?.name ?? "");
|
||||||
}
|
})
|
||||||
)
|
}
|
||||||
}
|
/>
|
||||||
>
|
) : (
|
||||||
<span className="outliner-item__title">{label}</span>
|
<button
|
||||||
</button>
|
className="outliner-item__select"
|
||||||
|
type="button"
|
||||||
|
data-testid={`outliner-brush-${brush.id}`}
|
||||||
|
onClick={() =>
|
||||||
|
applySelection(
|
||||||
|
{
|
||||||
|
kind: "brushes",
|
||||||
|
ids: [brush.id]
|
||||||
|
},
|
||||||
|
"outliner",
|
||||||
|
{
|
||||||
|
focusViewport: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span className="outliner-item__title">{label}</span>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
<button
|
<button
|
||||||
className="outliner-item__delete"
|
className="outliner-item__delete"
|
||||||
type="button"
|
type="button"
|
||||||
@@ -4239,26 +4258,6 @@ export function App({ store, initialStatusMessage }: AppProps) {
|
|||||||
x
|
x
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{selectedBrush?.id !== brush.id ? null : (
|
|
||||||
<label className="form-field outliner-item__editor">
|
|
||||||
<span className="label">Name</span>
|
|
||||||
<input
|
|
||||||
className="text-input text-input--dense"
|
|
||||||
data-testid="selected-brush-name"
|
|
||||||
type="text"
|
|
||||||
value={brushNameDraft}
|
|
||||||
placeholder={`Box Brush ${brushIndex + 1}`}
|
|
||||||
onChange={(event) => setBrushNameDraft(event.currentTarget.value)}
|
|
||||||
onBlur={applyBrushNameChange}
|
|
||||||
onKeyDown={(event) => {
|
|
||||||
if (event.key === "Enter") {
|
|
||||||
applyBrushNameChange();
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@@ -4272,47 +4271,66 @@ export function App({ store, initialStatusMessage }: AppProps) {
|
|||||||
<div className="outliner-empty">No model instances placed yet.</div>
|
<div className="outliner-empty">No model instances placed yet.</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="outliner-list" data-testid="outliner-model-instance-list">
|
<div className="outliner-list" data-testid="outliner-model-instance-list">
|
||||||
{modelInstanceDisplayList.map(({ modelInstance, label }) => (
|
{modelInstanceDisplayList.map(({ modelInstance, label }) => {
|
||||||
<div
|
const isSelected =
|
||||||
key={modelInstance.id}
|
editorState.selection.kind === "modelInstances" && editorState.selection.ids.includes(modelInstance.id);
|
||||||
className={`outliner-item ${
|
|
||||||
editorState.selection.kind === "modelInstances" && editorState.selection.ids.includes(modelInstance.id)
|
return (
|
||||||
? "outliner-item--selected"
|
<div
|
||||||
: ""
|
key={modelInstance.id}
|
||||||
} outliner-item--compact`}
|
className={`outliner-item ${isSelected ? "outliner-item--selected" : ""} outliner-item--compact`}
|
||||||
>
|
>
|
||||||
<div className="outliner-item__row">
|
<div className="outliner-item__row">
|
||||||
<button
|
{isSelected ? (
|
||||||
data-testid={`outliner-model-instance-${modelInstance.id}`}
|
<input
|
||||||
className="outliner-item__select"
|
className="outliner-item__rename"
|
||||||
type="button"
|
data-testid="selected-model-instance-name"
|
||||||
onClick={() =>
|
type="text"
|
||||||
applySelection(
|
value={modelInstanceNameDraft}
|
||||||
{
|
placeholder={editorState.document.assets[modelInstance.assetId]?.sourceName ?? "Model Instance"}
|
||||||
kind: "modelInstances",
|
onChange={(event) => setModelInstanceNameDraft(event.currentTarget.value)}
|
||||||
ids: [modelInstance.id]
|
onBlur={applyModelInstanceNameChange}
|
||||||
},
|
onFocus={(event) => event.currentTarget.select()}
|
||||||
"outliner",
|
onKeyDown={(event) =>
|
||||||
{
|
handleInlineNameInputKeyDown(event, () => {
|
||||||
focusViewport: true
|
setModelInstanceNameDraft(selectedModelInstance?.name ?? "");
|
||||||
|
})
|
||||||
}
|
}
|
||||||
)
|
/>
|
||||||
}
|
) : (
|
||||||
>
|
<button
|
||||||
<span className="outliner-item__title">{label}</span>
|
data-testid={`outliner-model-instance-${modelInstance.id}`}
|
||||||
</button>
|
className="outliner-item__select"
|
||||||
<button
|
type="button"
|
||||||
className="outliner-item__delete"
|
onClick={() =>
|
||||||
type="button"
|
applySelection(
|
||||||
data-testid={`outliner-delete-model-instance-${modelInstance.id}`}
|
{
|
||||||
aria-label={`Delete ${label}`}
|
kind: "modelInstances",
|
||||||
onClick={() => handleDeleteModelInstance(modelInstance.id)}
|
ids: [modelInstance.id]
|
||||||
>
|
},
|
||||||
x
|
"outliner",
|
||||||
</button>
|
{
|
||||||
|
focusViewport: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span className="outliner-item__title">{label}</span>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
<button
|
||||||
|
className="outliner-item__delete"
|
||||||
|
type="button"
|
||||||
|
data-testid={`outliner-delete-model-instance-${modelInstance.id}`}
|
||||||
|
aria-label={`Delete ${label}`}
|
||||||
|
onClick={() => handleDeleteModelInstance(modelInstance.id)}
|
||||||
|
>
|
||||||
|
x
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
);
|
||||||
))}
|
})}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -4324,47 +4342,65 @@ export function App({ store, initialStatusMessage }: AppProps) {
|
|||||||
|
|
||||||
{entityDisplayList.length === 0 ? null : (
|
{entityDisplayList.length === 0 ? null : (
|
||||||
<div className="outliner-list">
|
<div className="outliner-list">
|
||||||
{entityDisplayList.map(({ entity, label }) => (
|
{entityDisplayList.map(({ entity, label }) => {
|
||||||
<div
|
const isSelected = editorState.selection.kind === "entities" && editorState.selection.ids.includes(entity.id);
|
||||||
key={entity.id}
|
|
||||||
className={`outliner-item ${
|
return (
|
||||||
editorState.selection.kind === "entities" && editorState.selection.ids.includes(entity.id)
|
<div
|
||||||
? "outliner-item--selected"
|
key={entity.id}
|
||||||
: ""
|
className={`outliner-item ${isSelected ? "outliner-item--selected" : ""} outliner-item--compact`}
|
||||||
} outliner-item--compact`}
|
>
|
||||||
>
|
<div className="outliner-item__row">
|
||||||
<div className="outliner-item__row">
|
{isSelected ? (
|
||||||
<button
|
<input
|
||||||
data-testid={`outliner-entity-${entity.id}`}
|
className="outliner-item__rename"
|
||||||
className="outliner-item__select"
|
data-testid="selected-entity-name"
|
||||||
type="button"
|
type="text"
|
||||||
onClick={() =>
|
value={entityNameDraft}
|
||||||
applySelection(
|
placeholder={getEntityKindLabel(entity.kind)}
|
||||||
{
|
onChange={(event) => setEntityNameDraft(event.currentTarget.value)}
|
||||||
kind: "entities",
|
onBlur={applyEntityNameChange}
|
||||||
ids: [entity.id]
|
onFocus={(event) => event.currentTarget.select()}
|
||||||
},
|
onKeyDown={(event) =>
|
||||||
"outliner",
|
handleInlineNameInputKeyDown(event, () => {
|
||||||
{
|
setEntityNameDraft(selectedEntity?.name ?? "");
|
||||||
focusViewport: true
|
})
|
||||||
}
|
}
|
||||||
)
|
/>
|
||||||
}
|
) : (
|
||||||
>
|
<button
|
||||||
<span className="outliner-item__title">{label}</span>
|
data-testid={`outliner-entity-${entity.id}`}
|
||||||
</button>
|
className="outliner-item__select"
|
||||||
<button
|
type="button"
|
||||||
className="outliner-item__delete"
|
onClick={() =>
|
||||||
type="button"
|
applySelection(
|
||||||
data-testid={`outliner-delete-entity-${entity.id}`}
|
{
|
||||||
aria-label={`Delete ${label}`}
|
kind: "entities",
|
||||||
onClick={() => handleDeleteEntity(entity.id)}
|
ids: [entity.id]
|
||||||
>
|
},
|
||||||
x
|
"outliner",
|
||||||
</button>
|
{
|
||||||
|
focusViewport: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span className="outliner-item__title">{label}</span>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
<button
|
||||||
|
className="outliner-item__delete"
|
||||||
|
type="button"
|
||||||
|
data-testid={`outliner-delete-entity-${entity.id}`}
|
||||||
|
aria-label={`Delete ${label}`}
|
||||||
|
onClick={() => handleDeleteEntity(entity.id)}
|
||||||
|
>
|
||||||
|
x
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
);
|
||||||
))}
|
})}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user