mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-06 22:49:16 +00:00
committed by
claude[bot]
parent
557bc1fd85
commit
4dc0a538cc
@@ -5932,7 +5932,7 @@ export class HouseplanCard extends LitElement {
|
||||
saturation: this._t('color_picker.saturation'),
|
||||
value: this._t('color_picker.value'),
|
||||
hex: this._t('color_picker.hex'),
|
||||
invalidHex: this._t('color_picker.invalid_hex'),
|
||||
invalidHex: this._t('color_picker.invalid_hex'), confirm: this._t('color_picker.confirm'),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+58
-3
@@ -12,6 +12,7 @@ export type ColorPickerLabels = {
|
||||
value: string;
|
||||
hex: string;
|
||||
invalidHex: string;
|
||||
confirm: string;
|
||||
};
|
||||
|
||||
const DEFAULT_LABELS: ColorPickerLabels = {
|
||||
@@ -21,6 +22,7 @@ const DEFAULT_LABELS: ColorPickerLabels = {
|
||||
value: 'Brightness',
|
||||
hex: 'Hex color',
|
||||
invalidHex: 'Enter a 3- or 6-digit hex color',
|
||||
confirm: 'OK',
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -49,6 +51,10 @@ export class HpColorOpacity extends LitElement {
|
||||
private _value = 0;
|
||||
private _hexDraft = '#607d8b';
|
||||
private _hexInvalid = false;
|
||||
/** An invalid commit may normalize the visible draft back to a valid value.
|
||||
* Keep the error latched until the user actually types a new valid HEX so a
|
||||
* repeated confirmation cannot mistake that normalization for a correction. */
|
||||
private _hexNeedsValidInput = false;
|
||||
private _lastValidColor = '#607d8b';
|
||||
private _activePointerId: number | null = null;
|
||||
|
||||
@@ -303,6 +309,23 @@ export class HpColorOpacity extends LitElement {
|
||||
color: var(--secondary-text-color, #9aa4ad);
|
||||
font-size: 12px;
|
||||
}
|
||||
.confirm {
|
||||
width: 100%;
|
||||
min-height: 40px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid var(--primary-color, #03a9f4);
|
||||
border-radius: 6px;
|
||||
padding: 8px 12px;
|
||||
color: var(--text-primary-color, #fff);
|
||||
background: var(--primary-color, #03a9f4);
|
||||
cursor: pointer;
|
||||
font: inherit;
|
||||
font-weight: 600;
|
||||
}
|
||||
.confirm:focus-visible {
|
||||
outline: 2px solid var(--primary-text-color, #fff);
|
||||
outline-offset: -4px;
|
||||
}
|
||||
:host([disabled]) {
|
||||
opacity: .5;
|
||||
pointer-events: none;
|
||||
@@ -325,6 +348,12 @@ export class HpColorOpacity extends LitElement {
|
||||
.hue-range::-moz-range-thumb {
|
||||
box-shadow: none;
|
||||
}
|
||||
.confirm {
|
||||
border-color: ButtonText;
|
||||
color: HighlightText;
|
||||
background: Highlight;
|
||||
forced-color-adjust: none;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -415,6 +444,7 @@ export class HpColorOpacity extends LitElement {
|
||||
this._forceFallback = false;
|
||||
this._syncFromColor(this.color, false);
|
||||
this._hexInvalid = false;
|
||||
this._hexNeedsValidInput = false;
|
||||
this._activePointerId = null;
|
||||
this._open = true;
|
||||
await this.updateComplete;
|
||||
@@ -518,6 +548,7 @@ export class HpColorOpacity extends LitElement {
|
||||
value: labels.value || DEFAULT_LABELS.value,
|
||||
hex: labels.hex || DEFAULT_LABELS.hex,
|
||||
invalidHex: labels.invalidHex || DEFAULT_LABELS.invalidHex,
|
||||
confirm: labels.confirm || DEFAULT_LABELS.confirm,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -531,6 +562,7 @@ export class HpColorOpacity extends LitElement {
|
||||
this._value = hsv.v;
|
||||
this._hexDraft = normalized;
|
||||
this._hexInvalid = false;
|
||||
this._hexNeedsValidInput = false;
|
||||
this._lastValidColor = normalized;
|
||||
}
|
||||
|
||||
@@ -649,10 +681,14 @@ export class HpColorOpacity extends LitElement {
|
||||
private _hexInput(event: Event): void {
|
||||
const value = (event.target as HTMLInputElement).value;
|
||||
this._hexDraft = value;
|
||||
this._hexInvalid = false;
|
||||
const normalized = normalizeHexColor(value);
|
||||
const rgb = normalized ? hexToRgb(normalized) : null;
|
||||
if (!normalized || !rgb) return;
|
||||
if (!normalized || !rgb) {
|
||||
this._hexInvalid = this._hexNeedsValidInput;
|
||||
return;
|
||||
}
|
||||
this._hexNeedsValidInput = false;
|
||||
this._hexInvalid = false;
|
||||
const hsv = rgbToHsv(rgb);
|
||||
if (hsv.s > 0.0001) this._hue = hsv.h;
|
||||
this._saturation = hsv.s;
|
||||
@@ -665,13 +701,31 @@ export class HpColorOpacity extends LitElement {
|
||||
if (!normalized) {
|
||||
this._hexDraft = this._lastValidColor;
|
||||
this._hexInvalid = true;
|
||||
this._hexNeedsValidInput = true;
|
||||
return;
|
||||
}
|
||||
this._hexDraft = normalized;
|
||||
if (this._hexNeedsValidInput) {
|
||||
this._hexInvalid = true;
|
||||
return;
|
||||
}
|
||||
this._hexInvalid = false;
|
||||
if (normalized !== this._lastValidColor) this._emit(normalized, this.opacity);
|
||||
}
|
||||
|
||||
private _confirm(event: Event): void {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this._commitHex();
|
||||
if (this._hexInvalid || this._hexNeedsValidInput) {
|
||||
this.updateComplete.then(() => {
|
||||
this._surface()?.querySelector<HTMLInputElement>('input[type="text"]')?.focus();
|
||||
});
|
||||
return;
|
||||
}
|
||||
this._closePicker(true);
|
||||
}
|
||||
|
||||
private _hexKeyDown(event: KeyboardEvent): void {
|
||||
if (event.key !== 'Enter') return;
|
||||
event.preventDefault();
|
||||
@@ -689,7 +743,7 @@ export class HpColorOpacity extends LitElement {
|
||||
this.opacity = clamped;
|
||||
this._lastValidColor = normalized;
|
||||
if (!preserveHexDraft) this._hexDraft = normalized;
|
||||
this._hexInvalid = false;
|
||||
this._hexInvalid = this._hexNeedsValidInput;
|
||||
this.dispatchEvent(new CustomEvent('hp-color-opacity-change', {
|
||||
detail: { color: normalized, opacity: clamped },
|
||||
bubbles: true,
|
||||
@@ -763,6 +817,7 @@ export class HpColorOpacity extends LitElement {
|
||||
@change=${(e: Event) => this._setOpacity(Number((e.target as HTMLInputElement).value) / 100)} />
|
||||
<span class="pct">%</span>
|
||||
</div>` : nothing}
|
||||
<button class="confirm" type="button" @click=${(e: Event) => this._confirm(e)}>${labels.confirm}</button>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"color_picker.value": "Helligkeit",
|
||||
"color_picker.hex": "Hex-Farbe",
|
||||
"color_picker.invalid_hex": "Geben Sie eine 3- oder 6-stellige Hex-Farbe ein",
|
||||
"color_picker.confirm": "OK",
|
||||
"btn.properties": "Eigenschaften",
|
||||
"btn.keep_as_walls": "Als Wände behalten",
|
||||
"btn.delete_room_keep_walls": "Raum löschen, Wände behalten",
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"color_picker.value": "Brightness",
|
||||
"color_picker.hex": "Hex color",
|
||||
"color_picker.invalid_hex": "Enter a 3- or 6-digit hex color",
|
||||
"color_picker.confirm": "OK",
|
||||
"btn.properties": "Properties",
|
||||
"btn.keep_as_walls": "Keep as walls",
|
||||
"btn.delete_room_keep_walls": "Delete room, keep walls",
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"color_picker.value": "Luminosité",
|
||||
"color_picker.hex": "Couleur hexadécimale",
|
||||
"color_picker.invalid_hex": "Saisissez une couleur hexadécimale à 3 ou 6 chiffres",
|
||||
"color_picker.confirm": "OK",
|
||||
"btn.properties": "Propriétés",
|
||||
"btn.keep_as_walls": "Conserver comme murs",
|
||||
"btn.delete_room_keep_walls": "Supprimer la pièce, conserver les murs",
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"color_picker.value": "Яркость",
|
||||
"color_picker.hex": "Цвет HEX",
|
||||
"color_picker.invalid_hex": "Введите цвет HEX из 3 или 6 цифр",
|
||||
"color_picker.confirm": "ОК",
|
||||
"btn.properties": "Свойства",
|
||||
"btn.keep_as_walls": "Оставить стенами",
|
||||
"btn.delete_room_keep_walls": "Удалить комнату, оставить стены",
|
||||
|
||||
Reference in New Issue
Block a user