improve notepad features and add drawing canvas
All checks were successful
Deploy Sokko G / deploy (push) Successful in 7s
All checks were successful
Deploy Sokko G / deploy (push) Successful in 7s
This commit is contained in:
parent
e73d754082
commit
de1b8a5638
20 changed files with 1732 additions and 141 deletions
180
website/src/features/toolboxes/modules/DrawingControls.jsx
Normal file
180
website/src/features/toolboxes/modules/DrawingControls.jsx
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
// Rôle : rend les contrôles compacts des calques de dessin réutilisables.
|
||||
import { CompactDropdown } from "../../../components/CompactDropdown.jsx";
|
||||
import { Icon } from "../../../components/Icon.jsx";
|
||||
|
||||
const DEFAULT_WIDTHS = [2, 4, 8, 12];
|
||||
|
||||
export function DrawingControls({ textContent = {}, active, onToggleActive, eraseActive, onToggleErase, color, colors, onColorChange, width, widths = DEFAULT_WIDTHS, onWidthChange, onUndo, onClear, storageMode, onToggleStorageMode }) {
|
||||
return (
|
||||
<div className={`drawing-controls-panel ${active ? "is-open" : ""}`} aria-label={textContent.drawingLabel || "Dessin"}>
|
||||
<button className={`drawing-control-button ${active ? "active" : ""}`} type="button" aria-pressed={active} title={textContent.drawTitle || "Dessiner"} onClick={onToggleActive}>
|
||||
<Icon name="edit" />
|
||||
</button>
|
||||
{active && (
|
||||
<>
|
||||
<button
|
||||
className={`drawing-control-button ${eraseActive ? "active" : ""}`}
|
||||
type="button"
|
||||
aria-pressed={eraseActive}
|
||||
title={textContent.eraseTitle || "Gommer"}
|
||||
onClick={onToggleErase}
|
||||
>
|
||||
<Icon name="rubber" />
|
||||
</button>
|
||||
<DrawingColorDropdown
|
||||
label={textContent.drawingColorLabel || "Couleur du dessin"}
|
||||
colors={colors}
|
||||
value={color}
|
||||
onSelect={onColorChange}
|
||||
/>
|
||||
<DrawingWidthDropdown
|
||||
label={textContent.drawingWidthLabel || "Épaisseur du trait"}
|
||||
widths={widths}
|
||||
value={width}
|
||||
onSelect={onWidthChange}
|
||||
/>
|
||||
<button className="drawing-control-button" type="button" title={textContent.undoDrawingTitle || "Annuler le dernier trait"} onClick={onUndo}>
|
||||
<Icon name="back" />
|
||||
</button>
|
||||
<button className="drawing-control-button danger" type="button" title={textContent.clearDrawingTitle || "Effacer les dessins"} onClick={onClear}>
|
||||
<Icon name="trash" />
|
||||
</button>
|
||||
{onToggleStorageMode && (
|
||||
<button
|
||||
className={`module-scroll-button drawing-storage-switch ${storageMode === "permanent" ? "active" : ""}`}
|
||||
type="button"
|
||||
aria-pressed={storageMode === "permanent"}
|
||||
aria-label={storageMode === "permanent" ? textContent.permanentTitle || "Annotations permanentes" : textContent.temporaryTitle || "Annotations temporaires"}
|
||||
title={storageMode === "permanent" ? textContent.permanentTitle || "Annotations permanentes" : textContent.temporaryTitle || "Annotations temporaires"}
|
||||
onClick={onToggleStorageMode}
|
||||
>
|
||||
<Icon name="save" />
|
||||
<i aria-hidden="true" />
|
||||
</button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function FormattingColorDropdown({ label, sections }) {
|
||||
return (
|
||||
<CompactDropdown
|
||||
className="notepad-color-dropdown"
|
||||
menuClassName="notepad-color-menu is-sectioned"
|
||||
label={label}
|
||||
closeOnMouseLeave
|
||||
preventMouseDown
|
||||
renderTrigger={({ toggle }) => (
|
||||
<button className="notepad-color-toggle is-rainbow" type="button" title={label} aria-label={label} onClick={toggle} />
|
||||
)}
|
||||
>
|
||||
{({ close }) => (
|
||||
<>
|
||||
{sections.map((section) => (
|
||||
<div className="notepad-color-section" key={section.label}>
|
||||
<span className="notepad-color-section-label">{section.label}</span>
|
||||
<div className="notepad-color-section-swatches">
|
||||
{section.colors.map((color) => (
|
||||
<button
|
||||
key={`${section.label}-${color}`}
|
||||
className={`notepad-swatch ${section.value === color ? "active" : ""}`}
|
||||
type="button"
|
||||
title={`${section.label} ${color}`}
|
||||
aria-label={`${section.label} ${color}`}
|
||||
aria-pressed={section.value === color}
|
||||
style={{ "--swatch-color": color }}
|
||||
onClick={() => {
|
||||
section.onSelect(color);
|
||||
close();
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</CompactDropdown>
|
||||
);
|
||||
}
|
||||
|
||||
export function DrawingColorDropdown({ label, colors, value, onSelect }) {
|
||||
return (
|
||||
<CompactDropdown
|
||||
className="notepad-color-dropdown"
|
||||
menuClassName="notepad-color-menu"
|
||||
label={label}
|
||||
closeOnMouseLeave
|
||||
preventMouseDown
|
||||
renderTrigger={({ toggle }) => (
|
||||
<button
|
||||
className="notepad-color-toggle is-rainbow"
|
||||
type="button"
|
||||
title={label}
|
||||
aria-label={label}
|
||||
style={{ "--swatch-color": value }}
|
||||
onClick={toggle}
|
||||
/>
|
||||
)}
|
||||
>
|
||||
{({ close }) => (
|
||||
<>
|
||||
{colors.map((color) => (
|
||||
<button
|
||||
key={color}
|
||||
className={`notepad-swatch ${value === color ? "active" : ""}`}
|
||||
type="button"
|
||||
title={`${label} ${color}`}
|
||||
aria-label={`${label} ${color}`}
|
||||
aria-pressed={value === color}
|
||||
style={{ "--swatch-color": color }}
|
||||
onClick={() => {
|
||||
onSelect(color);
|
||||
close();
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</CompactDropdown>
|
||||
);
|
||||
}
|
||||
|
||||
export function DrawingWidthDropdown({ label, widths, value, onSelect }) {
|
||||
return (
|
||||
<CompactDropdown
|
||||
className="drawing-width-dropdown"
|
||||
menuClassName="drawing-width-menu"
|
||||
label={label}
|
||||
closeOnMouseLeave
|
||||
preventMouseDown
|
||||
renderTrigger={({ toggle }) => (
|
||||
<button className="drawing-width-toggle" type="button" title={label} aria-label={label} onClick={toggle}>
|
||||
<span style={{ "--line-width": `${value}px` }} />
|
||||
</button>
|
||||
)}
|
||||
>
|
||||
{({ close }) => (
|
||||
<>
|
||||
{widths.map((lineWidth) => (
|
||||
<button
|
||||
key={lineWidth}
|
||||
className={`drawing-width-button ${value === lineWidth ? "active" : ""}`}
|
||||
type="button"
|
||||
aria-pressed={value === lineWidth}
|
||||
title={`${label} ${lineWidth}`}
|
||||
onClick={() => {
|
||||
onSelect(lineWidth);
|
||||
close();
|
||||
}}
|
||||
>
|
||||
<span style={{ "--line-width": `${lineWidth}px` }} />
|
||||
</button>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</CompactDropdown>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue