feat: add gradient entity modal and fix color picker clipping
Add full gradient editor modal with name, description, visual stop editor, tags, and dirty checking. Gradient editor now supports ID prefix to avoid DOM conflicts between CSS editor and standalone modal. Fix color picker popover clipped by template-card overflow:hidden. Fix gradient canvas not sizing correctly in standalone modal.
This commit is contained in:
@@ -180,6 +180,7 @@
|
||||
{% include 'modals/device-settings.html' %}
|
||||
{% include 'modals/target-editor.html' %}
|
||||
{% include 'modals/css-editor.html' %}
|
||||
{% include 'modals/gradient-editor.html' %}
|
||||
{% include 'modals/test-css-source.html' %}
|
||||
{% include 'modals/notification-history.html' %}
|
||||
{% include 'modals/kc-editor.html' %}
|
||||
|
||||
@@ -212,16 +212,6 @@
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div id="css-editor-effect-custom-palette-group" class="form-group" style="display:none">
|
||||
<div class="label-row">
|
||||
<label for="css-editor-effect-custom-palette" data-i18n="color_strip.effect.custom_palette">Custom Palette:</label>
|
||||
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?" data-i18n-aria-label="aria.hint">?</button>
|
||||
</div>
|
||||
<small class="input-hint" style="display:none" data-i18n="color_strip.effect.custom_palette.hint">JSON array of [position, R, G, B] stops.</small>
|
||||
<textarea id="css-editor-effect-custom-palette" rows="3"
|
||||
placeholder='[[0,0,0,0],[0.5,255,0,0],[1,255,255,0]]'></textarea>
|
||||
</div>
|
||||
|
||||
<div id="css-editor-effect-color-group" class="form-group" style="display:none">
|
||||
<div class="label-row">
|
||||
<label for="css-editor-effect-color" data-i18n="color_strip.effect.color">Color:</label>
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
<!-- Gradient entity editor modal -->
|
||||
<div id="gradient-editor-modal" class="modal" role="dialog" aria-modal="true" aria-labelledby="gradient-editor-title">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h2 id="gradient-editor-title" data-i18n="gradient.add">Add Gradient</h2>
|
||||
<button class="modal-close-btn" onclick="closeGradientEditor()" data-i18n-aria-label="aria.close">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<input type="hidden" id="gradient-editor-id">
|
||||
<div id="gradient-editor-error" class="modal-error" style="display:none"></div>
|
||||
|
||||
<!-- Name + Tags (same form-group, matching other entities) -->
|
||||
<div class="form-group">
|
||||
<div class="label-row">
|
||||
<label for="gradient-editor-name" data-i18n="gradient.name">Name:</label>
|
||||
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?" data-i18n-aria-label="aria.hint">?</button>
|
||||
</div>
|
||||
<small class="input-hint" style="display:none" data-i18n="gradient.name.hint">A descriptive name for this gradient.</small>
|
||||
<input type="text" id="gradient-editor-name" required>
|
||||
<div id="gradient-editor-tags-container"></div>
|
||||
</div>
|
||||
|
||||
<!-- Description -->
|
||||
<div class="form-group">
|
||||
<div class="label-row">
|
||||
<label for="gradient-editor-description" data-i18n="gradient.description">Description:</label>
|
||||
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?" data-i18n-aria-label="aria.hint">?</button>
|
||||
</div>
|
||||
<small class="input-hint" style="display:none" data-i18n="gradient.description.hint">Optional description for this gradient.</small>
|
||||
<input type="text" id="gradient-editor-description" maxlength="500">
|
||||
</div>
|
||||
|
||||
<!-- Gradient preview + markers (unique IDs prefixed ge-) -->
|
||||
<div class="form-group">
|
||||
<div class="label-row">
|
||||
<label data-i18n="color_strip.gradient.preview">Gradient:</label>
|
||||
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?" data-i18n-aria-label="aria.hint">?</button>
|
||||
</div>
|
||||
<small class="input-hint" style="display:none" data-i18n="color_strip.gradient.preview.hint">Visual preview. Click the marker track below to add a stop. Drag markers to reposition.</small>
|
||||
<div class="gradient-editor">
|
||||
<canvas id="ge-gradient-canvas" height="44"></canvas>
|
||||
<div id="ge-gradient-markers-track" class="gradient-markers-track"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Color stops list -->
|
||||
<div class="form-group">
|
||||
<div class="label-row">
|
||||
<label data-i18n="color_strip.gradient.stops">Color Stops:</label>
|
||||
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?" data-i18n-aria-label="aria.hint">?</button>
|
||||
</div>
|
||||
<small class="input-hint" style="display:none" data-i18n="color_strip.gradient.stops.hint">Each stop defines a color at a relative position (0.0 = start, 1.0 = end). The ↔ button adds a right-side color to create a hard edge at that stop.</small>
|
||||
<div id="ge-gradient-stops-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-icon btn-secondary" onclick="closeGradientEditor()" title="Cancel" data-i18n-title="settings.button.cancel" data-i18n-aria-label="aria.cancel">✕</button>
|
||||
<button class="btn btn-icon btn-primary" onclick="saveGradientEntity()" title="Save" data-i18n-title="settings.button.save" data-i18n-aria-label="aria.save">✓</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user