feat: refactor popups with shared positioning and CSS tooltips

- Add usePopupPosition composable for smart popup positioning
  (bottom-right → bottom-left → top-right → top-left fallback)
- Refactor ElementPopup with complete controls matching mockup
- Add stylesheet sync: popups initialize from and watch store changes
- Add click-to-close behavior: clicking another element closes popup
- Add CSS property tooltips on all form labels (editor panel + popups)
  with dotted underline and monospace code tooltip on hover
- Add field--view-only class and disabled attribute on locked fields

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
isUnknown 2025-12-05 18:21:54 +01:00
parent 25ef4685c1
commit cf1dadb1b3
10 changed files with 1178 additions and 159 deletions

View file

@ -9,14 +9,14 @@
<!-- Police -->
<div class="settings-subsection">
<div class="field">
<label for="text-font">Police</label>
<label for="text-font" class="label-with-tooltip" data-css="font-family">Police</label>
<div class="field-with-option">
<select id="text-font" v-model="font">
<option v-for="f in fonts" :key="f" :value="f">{{ f }}</option>
</select>
<div class="field-checkbox">
<input id="text-italic" type="checkbox" v-model="italic" />
<label for="text-italic">Italique</label>
<label for="text-italic" class="label-with-tooltip" data-css="font-style">Italique</label>
</div>
</div>
</div>
@ -25,7 +25,7 @@
<!-- Graisse -->
<div class="settings-subsection">
<div class="field">
<label>Graisse</label>
<label class="label-with-tooltip" data-css="font-weight">Graisse</label>
<UnitToggle v-model="weight" :units="weights" />
</div>
</div>
@ -33,7 +33,7 @@
<!-- Taille du texte -->
<div class="settings-subsection">
<div class="field">
<label for="text-size-range">Taille du texte</label>
<label for="text-size-range" class="label-with-tooltip" data-css="font-size">Taille du texte</label>
<InputWithUnit
v-model="fontSize"
:units="['px', 'em', 'rem']"
@ -47,7 +47,7 @@
<!-- Alignement -->
<div class="settings-subsection">
<div class="field">
<label for="text-alignment">Alignement</label>
<label for="text-alignment" class="label-with-tooltip" data-css="text-align">Alignement</label>
<select id="text-alignment" v-model="alignment">
<option v-for="a in alignments" :key="a.value" :value="a.value">
{{ a.label }}
@ -59,7 +59,7 @@
<!-- Couleurs -->
<div class="settings-subsection">
<div class="field">
<label for="text-color">Couleur</label>
<label for="text-color" class="label-with-tooltip" data-css="color">Couleur</label>
<div class="input-with-color">
<input
id="text-color"
@ -71,7 +71,7 @@
</div>
</div>
<div class="field">
<label for="text-background">Arrière-plan</label>
<label for="text-background" class="label-with-tooltip" data-css="background">Arrière-plan</label>
<div class="input-with-color">
<input
id="text-background"
@ -90,6 +90,7 @@
ref="marginOuterEditor"
id="margin-outer"
label="Marges extérieures"
cssProperty="margin"
v-model:simple="marginOuter"
v-model:detailed="marginOuterDetailed"
:units="['mm', 'px', 'rem']"
@ -103,6 +104,7 @@
ref="marginInnerEditor"
id="margin-inner"
label="Marges intérieures"
cssProperty="padding"
v-model:simple="marginInner"
v-model:detailed="marginInnerDetailed"
:units="['mm', 'px', 'rem']"