196 lines
8.7 KiB
JavaScript
196 lines
8.7 KiB
JavaScript
// Rôle : rend le formulaire de création et édition des combos.
|
||
import { Icon } from "../../../components/Icon.jsx";
|
||
import { ComboInputToken, ComboSequence } from "./CombosParts.jsx";
|
||
import {
|
||
DEVICE_OPTIONS,
|
||
createInput,
|
||
getHoldSeconds
|
||
} from "./combosUtils.js";
|
||
|
||
export function CombosEditor({
|
||
data,
|
||
textContent,
|
||
comboCategory,
|
||
comboName,
|
||
customKey,
|
||
keyboardLayout,
|
||
paletteColumns,
|
||
draftInputs,
|
||
cleanDraftInputs,
|
||
activeStepIndex,
|
||
selectedInput,
|
||
selectedDraftInput,
|
||
simultaneousMode,
|
||
editingComboId,
|
||
onDeviceChange,
|
||
onKeyboardLayoutChange,
|
||
onComboCategoryChange,
|
||
onComboNameChange,
|
||
onCustomKeyChange,
|
||
onCustomKeyAdd,
|
||
onComboSave,
|
||
onDraftInputAdd,
|
||
onPaletteInputDrag,
|
||
onDraftInputDrag,
|
||
onInputDrop,
|
||
onNewStepDrop,
|
||
onStepSelect,
|
||
onInputSelect,
|
||
onSelectedInputHoldToggle,
|
||
onSelectedInputHoldChange,
|
||
onSimultaneousModeToggle,
|
||
onLastInputRemove,
|
||
onActiveStepRemove,
|
||
onComboEditCancel
|
||
}) {
|
||
return (
|
||
<div className="module-add-panel combos-editor">
|
||
<div className="combos-device-row">
|
||
<label>
|
||
<span>{textContent.deviceLabel || "Périphérique"}</span>
|
||
<select className="nds-select" data-size="sm" value={data.device} onChange={(event) => onDeviceChange(event.target.value)}>
|
||
{DEVICE_OPTIONS.map((device) => (
|
||
<option key={device.value} value={device.value}>{device.label}</option>
|
||
))}
|
||
</select>
|
||
</label>
|
||
{data.device === "keyboardMouse" && (
|
||
<div className="combos-keyboard-layout-switch nds-radio-button-group" data-size="sm" role="group" aria-label={textContent.keyboardLayoutLabel || "Disposition clavier"}>
|
||
{[
|
||
{ value: "azerty", label: "AZERTY" },
|
||
{ value: "qwerty", label: "QWERTY" }
|
||
].map((layout) => (
|
||
<button
|
||
key={layout.value}
|
||
type="button"
|
||
className={keyboardLayout === layout.value ? "active" : ""}
|
||
onClick={() => onKeyboardLayoutChange(layout.value)}
|
||
aria-pressed={keyboardLayout === layout.value}
|
||
>
|
||
{layout.label}
|
||
</button>
|
||
))}
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
<form className="combos-add-form" onSubmit={onComboSave}>
|
||
<div className="combos-form-grid">
|
||
<label>
|
||
<span>{textContent.targetCategoryLabel || "Catégorie"}</span>
|
||
<input className="nds-input" data-size="sm" type="text" value={comboCategory} onChange={(event) => onComboCategoryChange(event.target.value)} placeholder={textContent.noCategoryLabel || "Sans catégorie"} />
|
||
</label>
|
||
<label>
|
||
<span>{textContent.comboNameLabel || "Nom"}</span>
|
||
<input className="nds-input" data-size="sm" type="text" value={comboName} onChange={(event) => onComboNameChange(event.target.value)} placeholder={textContent.comboNamePlaceholder || "Nom du combo"} />
|
||
</label>
|
||
</div>
|
||
<div className="combos-palette" aria-label={textContent.paletteLabel || "Palette de touches"}>
|
||
{paletteColumns.map((columnGroups, columnIndex) => (
|
||
<div className="combos-palette-column" key={columnIndex}>
|
||
{columnGroups.map((group) => (
|
||
<div className={`combos-palette-group ${group.kind === "directions" ? "is-direction-grid" : ""}`} key={group.title}>
|
||
<span>{group.title}</span>
|
||
<div>
|
||
{group.inputs.map((input, inputIndex) => {
|
||
if (!input) return <span className="combo-palette-empty-cell" key={`empty-${inputIndex}`} aria-hidden="true" />;
|
||
const [kind, value] = input;
|
||
return (
|
||
<ComboInputToken
|
||
key={`${kind}-${value}`}
|
||
input={createInput(kind, value)}
|
||
device={data.device}
|
||
palette
|
||
onClick={() => onDraftInputAdd(kind, value)}
|
||
onDragStart={(event) => onPaletteInputDrag(event, kind, value)}
|
||
/>
|
||
);
|
||
})}
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
{data.device === "keyboardMouse" && (
|
||
<div className="inline-form combos-custom-key-form">
|
||
<input className="nds-input" data-size="sm" type="text" value={customKey} onChange={(event) => onCustomKeyChange(event.target.value)} placeholder={textContent.customKeyPlaceholder || "Touche personnalisée"} />
|
||
<button className="nds-button" data-size="sm" type="button" onClick={onCustomKeyAdd}>{textContent.addCustomKeyButton || "Ajouter touche"}</button>
|
||
</div>
|
||
)}
|
||
|
||
<div className="combo-draft-panel">
|
||
<ComboSequence
|
||
inputs={draftInputs}
|
||
device={data.device}
|
||
emptyLabel={textContent.emptyDraft || "Aucune touche sélectionnée."}
|
||
activeStepIndex={activeStepIndex}
|
||
selectedInput={selectedInput}
|
||
onSelectStep={onStepSelect}
|
||
onSelectInput={onInputSelect}
|
||
onDropInput={onInputDrop}
|
||
onDropNewStep={onNewStepDrop}
|
||
onDragInput={onDraftInputDrag}
|
||
/>
|
||
<div className="combo-draft-actions">
|
||
<label className="combo-hold-field">
|
||
<span className="combo-hold-controls nds-compound-toggle-field">
|
||
<button
|
||
type="button"
|
||
className={selectedDraftInput?.hold || selectedDraftInput?.holdMs ? "active" : ""}
|
||
onClick={onSelectedInputHoldToggle}
|
||
disabled={!selectedDraftInput}
|
||
aria-pressed={Boolean(selectedDraftInput?.hold || selectedDraftInput?.holdMs)}
|
||
>
|
||
{textContent.holdToggleLabel || "Hold"}
|
||
</button>
|
||
<input
|
||
className="nds-compound-toggle-field-input"
|
||
type="number"
|
||
min="0"
|
||
max="99"
|
||
step="1"
|
||
inputMode="numeric"
|
||
value={selectedDraftInput ? getHoldSeconds(selectedDraftInput) || "" : ""}
|
||
onChange={(event) => onSelectedInputHoldChange(event.target.value)}
|
||
disabled={!selectedDraftInput}
|
||
placeholder="0"
|
||
aria-label={textContent.holdLabel || "Maintien en secondes"}
|
||
/>
|
||
</span>
|
||
</label>
|
||
<button
|
||
type="button"
|
||
className={`combos-simultaneous-toggle nds-radio-button-group ${simultaneousMode ? "active" : ""}`}
|
||
data-size="xs"
|
||
onClick={onSimultaneousModeToggle}
|
||
aria-pressed={simultaneousMode}
|
||
title={textContent.simultaneousModeTitle || "Ajout simultané"}
|
||
aria-label={textContent.simultaneousModeTitle || "Ajout simultané"}
|
||
>
|
||
<span className={!simultaneousMode ? "active" : ""}>{textContent.successiveModeLabel || "A › B"}</span>
|
||
<span className={simultaneousMode ? "active" : ""}>{textContent.simultaneousModeLabel || "A + B"}</span>
|
||
</button>
|
||
<button type="button" className="notepad-toolbar-button nds-icon-button" data-size="sm" onClick={onLastInputRemove} disabled={!cleanDraftInputs.length} title={textContent.removeLastInputTitle || "Retirer la dernière touche"} aria-label={textContent.removeLastInputTitle || "Retirer la dernière touche"}>
|
||
<Icon name="back" />
|
||
</button>
|
||
<button type="button" className="notepad-toolbar-button nds-icon-button" data-size="sm" data-variant="danger" onClick={onActiveStepRemove} disabled={draftInputs.length <= 1} title={textContent.removeStepTitle || "Supprimer l'étape"} aria-label={textContent.removeStepTitle || "Supprimer l'étape"}>
|
||
<Icon name="trash" />
|
||
</button>
|
||
<div className="combo-save-actions">
|
||
{editingComboId && (
|
||
<button type="button" className="combo-cancel-button nds-button" data-size="sm" onClick={onComboEditCancel}>
|
||
{textContent.cancelEditButton || "Annuler"}
|
||
</button>
|
||
)}
|
||
<button className="nds-button" data-size="sm" data-variant="primary" disabled={!comboName.trim() && !cleanDraftInputs.length}>
|
||
{editingComboId ? textContent.saveComboButton || "Enregistrer" : textContent.addComboButton || "Ajouter le combo"}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
);
|
||
}
|