sokko-g/website/src/features/toolboxes/modules/CombosEditor.jsx
Shinuwa 817e21567b
All checks were successful
Deploy Sokko G / deploy (push) Successful in 17s
Migrate site controls to Nebula design system
2026-08-29 09:16:58 +02:00

196 lines
8.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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>
);
}