style panel settings

This commit is contained in:
Julie Blanc 2026-03-07 19:59:01 +01:00
parent d604e5d05e
commit 3ae2d0e310
12 changed files with 334 additions and 338 deletions

View file

@ -415,48 +415,5 @@ defineExpose({ handleIframeClick, close: handleClose, visible });
/* Toggle setting checkbox */
/* .toggle-setting {
cursor: pointer;
accent-color: var(--color-purple, #7c3aed);
flex-shrink: 0;
} */
/* Disabled state: grey out body but keep header interactive */
/* Clicking anywhere on the section enables it */
/* .setting-disabled {
cursor: pointer;
}
.setting-disabled .setting__body {
opacity: 0.4;
pointer-events: none;
}
.lock-toggle {
display: flex;
align-items: center;
justify-content: center;
background: none;
border: 1px solid transparent;
border-radius: 3px;
cursor: pointer;
padding: 2px 4px;
color: var(--color-text-muted, #999);
transition: color 0.15s, border-color 0.15s;
}
.lock-toggle:hover:not(:disabled) {
color: var(--color-text, #333);
border-color: var(--color-border, #ccc);
}
.lock-toggle.locked {
color: var(--color-purple, #7c3aed);
}
.lock-toggle:disabled {
opacity: 0.4;
cursor: not-allowed;
} */
</style>

View file

@ -1,249 +1,151 @@
<template>
<section
class="settings__container"
class="panel-settings__container"
id="settings__container_page"
data-color-type="page"
>
<h2>Réglage des pages</h2>
<div class="settings__header">
<div class="icon" v-html="bookIcon"></div>
<h2 class="title">Réglage des pages</h2>
</div>
<div class="container">
<div class="setting__section">
<div class="field field-simple">
<label for="page-format" class="label-with-tooltip" data-css="size"
>Format d'impression</label
>
<!-- Format d'impression -->
<div class="setting__section" data-setting="format">
<div class="setting__header">
<label class="label-with-tooltip" data-css="size">Format d'impression</label>
</div>
<div class="setting__body">
<select id="page-format" v-model="pageFormat">
<option value="A4">A4</option>
<option value="A5">A5</option>
<!-- <option value="A3">A3</option>
<option value="letter">Letter</option>
<option value="legal">Legal</option> -->
<option value="custom">Personnalisé</option>
</select>
</div>
</div>
<div class="setting__section">
<div
class="field field-margin"
:class="{ 'field--view-only': !isCustomFormat }"
>
<label for="page-width" class="label-with-tooltip" data-css="width"
>Largeur</label
>
<div class="input-with-unit">
<NumberInput
id="page-width"
:modelValue="customWidth"
@update:modelValue="(v) => (customWidth = v)"
:min="50"
:step="1"
:disabled="!isCustomFormat"
/>
<div class="unit-toggle">
<button type="button" class="active">mm</button>
<!-- Dimensions -->
<div class="setting__section" data-setting="dimensions" :class="{ 'setting-disabled': !isCustomFormat }">
<div class="setting__header">
<label class="label-with-tooltip" data-css="width / height">Dimensions</label>
</div>
<div class="setting__body">
<div class="field-size-page">
<label for="page-width" class="label-with-tooltip" data-css="width">Largeur</label>
<div class="input-with-unit">
<NumberInput
id="page-width"
:modelValue="customWidth"
@update:modelValue="(v) => (customWidth = v)"
:min="50"
:step="1"
:disabled="!isCustomFormat"
/>
<div class="unit-toggle">
<button type="button" class="active">mm</button>
</div>
</div>
</div>
</div>
<div
class="field field-margin"
:class="{ 'field--view-only': !isCustomFormat }"
>
<label for="page-height" class="label-with-tooltip" data-css="height"
>Hauteur</label
>
<div class="input-with-unit">
<NumberInput
id="page-height"
:modelValue="customHeight"
@update:modelValue="(v) => (customHeight = v)"
:min="50"
:step="1"
:disabled="!isCustomFormat"
/>
<div class="unit-toggle">
<button type="button" class="active">mm</button>
<div class="field-size-page">
<label for="page-height" class="label-with-tooltip" data-css="height">Hauteur</label>
<div class="input-with-unit">
<NumberInput
id="page-height"
:modelValue="customHeight"
@update:modelValue="(v) => (customHeight = v)"
:min="50"
:step="1"
:disabled="!isCustomFormat"
/>
<div class="unit-toggle">
<button type="button" class="active">mm</button>
</div>
</div>
</div>
</div>
</div>
<div class="setting__section margins">
<h3>Marges</h3>
<div class="field field-margin">
<label
for="margin-top"
class="label-with-tooltip"
data-css="margin-top"
>Haut</label
>
<div class="input-with-unit">
<NumberInput
id="margin-top"
:modelValue="margins.top.value"
:min="0"
:step="1"
@update:modelValue="(value) => (margins.top.value = value)"
/>
<div class="unit-toggle">
<button
type="button"
:class="{ active: margins.top.unit === 'mm' }"
@click="updateMarginUnit('top', 'mm')"
>
mm
</button>
<button
type="button"
:class="{ active: margins.top.unit === 'px' }"
@click="updateMarginUnit('top', 'px')"
>
px
</button>
<!-- <button
type="button"
:class="{ active: margins.top.unit === 'rem' }"
@click="updateMarginUnit('top', 'rem')"
>
rem
</button> -->
<!-- Marges -->
<div class="setting__section" data-setting="margin">
<div class="setting__header">
<label class="label-with-tooltip" data-css="margin">Marges</label>
</div>
<div class="setting__body">
<div class="field field-margin">
<label for="margin-top" class="label-with-tooltip" data-css="margin-top">Haut</label>
<div class="input-with-unit">
<NumberInput
id="margin-top"
:modelValue="margins.top.value"
:min="0"
:step="1"
@update:modelValue="(value) => (margins.top.value = value)"
/>
<div class="unit-toggle">
<button type="button" :class="{ active: margins.top.unit === 'mm' }" @click="updateMarginUnit('top', 'mm')">mm</button>
<button type="button" :class="{ active: margins.top.unit === 'px' }" @click="updateMarginUnit('top', 'px')">px</button>
</div>
</div>
</div>
</div>
<div class="field field-margin">
<label
for="margin-bottom"
class="label-with-tooltip"
data-css="margin-bottom"
>Bas</label
>
<div class="input-with-unit">
<NumberInput
id="margin-bottom"
:modelValue="margins.bottom.value"
:min="0"
:step="1"
@update:modelValue="(value) => (margins.bottom.value = value)"
/>
<div class="unit-toggle">
<button
type="button"
:class="{ active: margins.bottom.unit === 'mm' }"
@click="updateMarginUnit('bottom', 'mm')"
>
mm
</button>
<button
type="button"
:class="{ active: margins.bottom.unit === 'px' }"
@click="updateMarginUnit('bottom', 'px')"
>
px
</button>
<!-- <button
type="button"
:class="{ active: margins.bottom.unit === 'rem' }"
@click="updateMarginUnit('bottom', 'rem')"
>
rem
</button> -->
<div class="field field-margin">
<label for="margin-bottom" class="label-with-tooltip" data-css="margin-bottom">Bas</label>
<div class="input-with-unit">
<NumberInput
id="margin-bottom"
:modelValue="margins.bottom.value"
:min="0"
:step="1"
@update:modelValue="(value) => (margins.bottom.value = value)"
/>
<div class="unit-toggle">
<button type="button" :class="{ active: margins.bottom.unit === 'mm' }" @click="updateMarginUnit('bottom', 'mm')">mm</button>
<button type="button" :class="{ active: margins.bottom.unit === 'px' }" @click="updateMarginUnit('bottom', 'px')">px</button>
</div>
</div>
</div>
</div>
<div class="field field-margin">
<label
for="margin-left"
class="label-with-tooltip"
data-css="margin-left"
>Gauche</label
>
<div class="input-with-unit">
<NumberInput
id="margin-left"
:modelValue="margins.left.value"
:min="0"
:step="1"
@update:modelValue="(value) => (margins.left.value = value)"
/>
<div class="unit-toggle">
<button
type="button"
:class="{ active: margins.left.unit === 'mm' }"
@click="updateMarginUnit('left', 'mm')"
>
mm
</button>
<button
type="button"
:class="{ active: margins.left.unit === 'px' }"
@click="updateMarginUnit('left', 'px')"
>
px
</button>
<!-- <button
type="button"
:class="{ active: margins.left.unit === 'rem' }"
@click="updateMarginUnit('left', 'rem')"
>
rem
</button> -->
<div class="field field-margin">
<label for="margin-left" class="label-with-tooltip" data-css="margin-left">Gauche</label>
<div class="input-with-unit">
<NumberInput
id="margin-left"
:modelValue="margins.left.value"
:min="0"
:step="1"
@update:modelValue="(value) => (margins.left.value = value)"
/>
<div class="unit-toggle">
<button type="button" :class="{ active: margins.left.unit === 'mm' }" @click="updateMarginUnit('left', 'mm')">mm</button>
<button type="button" :class="{ active: margins.left.unit === 'px' }" @click="updateMarginUnit('left', 'px')">px</button>
</div>
</div>
</div>
</div>
<div class="field field-margin">
<label
for="margin-right"
class="label-with-tooltip"
data-css="margin-right"
>Droite</label
>
<div class="input-with-unit">
<NumberInput
id="margin-right"
:modelValue="margins.right.value"
:min="0"
:step="1"
@update:modelValue="(value) => (margins.right.value = value)"
/>
<div class="unit-toggle">
<button
type="button"
:class="{ active: margins.right.unit === 'mm' }"
@click="updateMarginUnit('right', 'mm')"
>
mm
</button>
<button
type="button"
:class="{ active: margins.right.unit === 'px' }"
@click="updateMarginUnit('right', 'px')"
>
px
</button>
<!-- <button
type="button"
:class="{ active: margins.right.unit === 'rem' }"
@click="updateMarginUnit('right', 'rem')"
>
rem
</button> -->
<div class="field field-margin">
<label for="margin-right" class="label-with-tooltip" data-css="margin-right">Droite</label>
<div class="input-with-unit">
<NumberInput
id="margin-right"
:modelValue="margins.right.value"
:min="0"
:step="1"
@update:modelValue="(value) => (margins.right.value = value)"
/>
<div class="unit-toggle">
<button type="button" :class="{ active: margins.right.unit === 'mm' }" @click="updateMarginUnit('right', 'mm')">mm</button>
<button type="button" :class="{ active: margins.right.unit === 'px' }" @click="updateMarginUnit('right', 'px')">px</button>
</div>
</div>
</div>
</div>
</div>
<div class="setting__section">
<div class="field field-simple">
<label
for="background"
class="label-with-tooltip"
data-css="background"
>Arrière-plan</label
>
<!-- Arrière-plan -->
<div class="setting__section" data-setting="background">
<div class="setting__header">
<label class="label-with-tooltip" data-css="background">Arrière-plan</label>
</div>
<div class="setting__body">
<div class="input-with-color">
<input
ref="backgroundColorInput"
@ -252,35 +154,16 @@
v-model="background.value"
data-coloris
/>
<!-- Temporarily commented out
<div class="unit-toggle">
<button
type="button"
:class="{ active: background.format === 'rgb' }"
@click="background.format = 'rgb'"
>
rgb
</button>
<button
type="button"
:class="{ active: background.format === 'hex' }"
@click="background.format = 'hex'"
>
hex
</button>
</div>
--></div>
</div>
</div>
<div class="setting__section" title="Fonctionnalité à venir">
<div class="field field-simple field--view-only">
<label
for="pattern"
class="label-with-tooltip"
data-css="background-image"
>Motif</label
>
<!-- Motif -->
<div class="setting__section setting-disabled" data-setting="pattern" title="Fonctionnalité à venir">
<div class="setting__header">
<label class="label-with-tooltip" data-css="background-image">Motif</label>
</div>
<div class="setting__body">
<select id="pattern" v-model="pattern" disabled>
<option value="">Choisissez</option>
<option value="dots">Points</option>
@ -290,33 +173,30 @@
</div>
</div>
<div class="setting__section">
<div class="field checkbox-field">
<input id="page-numbers" type="checkbox" v-model="pageNumbers" />
<label
for="page-numbers"
class="label-with-tooltip"
data-css="@bottom-left/right"
>Numéro de page</label
>
<!-- Options -->
<div class="setting__section" data-setting="options">
<div class="setting__header">
<label>Options</label>
</div>
<div class="field checkbox-field">
<input id="running-title" type="checkbox" v-model="runningTitle" />
<label
for="running-title"
class="label-with-tooltip"
data-css="string-set"
>Titre courant</label
>
<div class="setting__body">
<div class="field-checkbox">
<input id="page-numbers" type="checkbox" v-model="pageNumbers" />
<label for="page-numbers" class="label-with-tooltip" data-css="@bottom-left/right">Numéro de page</label>
</div>
<div class="field-checkbox">
<input id="running-title" type="checkbox" v-model="runningTitle" />
<label for="running-title" class="label-with-tooltip" data-css="string-set">Titre courant</label>
</div>
</div>
</div>
</div>
</section>
</template>
<script setup>
import { ref, computed, watch, onMounted, inject } from 'vue';
import bookIcon from '/assets/svg/book.svg?raw';
import { useStylesheetStore } from '../../stores/stylesheet';
import { useDebounce } from '../../composables/useDebounce';
import { useCssSync } from '../../composables/useCssSync';

View file

@ -1,30 +1,34 @@
<template>
<section class="settings__container" id="settings__container_elem" data-color-type="elem">
<h2>Réglage du texte par défaut</h2>
<section class="panel-settings__container" id="settings__container_elem" data-color-type="text">
<div class="settings__header">
<div class="icon" v-html="textIcon"></div>
<h2 class="title">Réglage du texte par défaut</h2>
</div>
<div class="container">
<p class="infos">
Ces réglages s'appliquent à l'ensemble des éléments du document. Vous
pouvez modifier ensuite les éléments indépendamment.
</p>
<!-- Police -->
<div class="setting__section">
<div class="field field-font">
<label for="text-font" class="label-with-tooltip" data-css="font-family">Police</label>
<div class="field-font__options">
<select id="text-font" v-model="font">
<option value="sans-serif">Police système (sans-serif)</option>
<option v-for="f in projectFonts" :key="f.name" :value="f.name" :style="{ fontFamily: `'${f.name}', ${f.category}` }">{{ f.name }}</option>
</select>
</div>
<div class="setting__section" data-setting="font">
<div class="setting__header">
<label class="label-with-tooltip" data-css="font-family">Police</label>
</div>
<div class="setting__body">
<select id="text-font" v-model="font">
<option value="sans-serif">Police système (sans-serif)</option>
<option v-for="f in projectFonts" :key="f.name" :value="f.name" :style="{ fontFamily: `'${f.name}', ${f.category}` }">{{ f.name }}</option>
</select>
</div>
</div>
<!-- Taille du texte -->
<div class="setting__section">
<div class="field field-text-size">
<label for="text-size-range" class="label-with-tooltip" data-css="font-size">Taille du texte</label>
<div class="setting__section" data-setting="fontSize">
<div class="setting__header">
<label class="label-with-tooltip" data-css="font-size">Taille du texte</label>
</div>
<div class="setting__body">
<InputWithUnit
v-model="fontSize"
:units="['px']"
@ -36,9 +40,11 @@
</div>
<!-- Interlignage -->
<div class="setting__section">
<div class="field field-text-size">
<label for="text-lineheight-range" class="label-with-tooltip" data-css="line-height">Interlignage</label>
<div class="setting__section" data-setting="lineHeight">
<div class="setting__header">
<label class="label-with-tooltip" data-css="line-height">Interlignage</label>
</div>
<div class="setting__body">
<InputWithUnit
v-model="lineHeight"
:units="['px']"
@ -49,17 +55,18 @@
</div>
</div>
<!-- Couleurs -->
<div class="setting__section">
<div class="field field-simple">
<label for="text-color" class="label-with-tooltip" data-css="color">Couleur</label>
<!-- Couleur -->
<div class="setting__section" data-setting="color">
<div class="setting__header">
<label class="label-with-tooltip" data-css="color">Couleur</label>
</div>
<div class="setting__body">
<div class="input-with-color">
<input
ref="colorInput"
id="text-color"
type="text"
v-model="color"
class="color-input"
data-coloris
/>
</div>
@ -73,6 +80,7 @@
<script setup>
import { ref, watch, onMounted, nextTick } from 'vue';
import textIcon from '/assets/svg/text.svg?raw';
import { initColoris } from '../../composables/useColoris';
import InputWithUnit from '../ui/InputWithUnit.vue';
import { useCssUpdater } from '../../composables/useCssUpdater';

View file

@ -372,12 +372,17 @@ export function useElementSettings({ margin, padding, basePopup }) {
if (hasAnyProp) {
for (const prop of styleProps) {
if (prop.group !== group || !(prop.css in parsed)) continue;
if (prop.css === 'font-family') {
const firstFont = parsed[prop.css].split(',')[0].trim().replace(/['"]/g, '');
fontFamily.value = firstFont;
if (prop.group !== group) continue;
if (prop.css in parsed) {
if (prop.css === 'font-family') {
const firstFont = parsed[prop.css].split(',')[0].trim().replace(/['"]/g, '');
fontFamily.value = firstFont;
} else {
prop.set(parsed[prop.css]);
}
} else {
prop.set(parsed[prop.css]);
// Property removed from CSS: reset to default
prop.set('normal');
}
}
for (const prop of unitProps) {