From ae4463cc88e4c19a9d0976ba6c74c658e347d9b0 Mon Sep 17 00:00:00 2001 From: Aleix Soler Date: Sat, 19 Jul 2025 12:49:06 +0200 Subject: [PATCH] chore: improve UI/UX CustomStatusItem component --- .../SettingsUI.tsx/CustomStatusItem.tsx | 236 +++++++++++++++--- styles/components/settings.css | 2 + 2 files changed, 205 insertions(+), 33 deletions(-) diff --git a/components/SettingsUI.tsx/CustomStatusItem.tsx b/components/SettingsUI.tsx/CustomStatusItem.tsx index 7e9aefb..4571cad 100644 --- a/components/SettingsUI.tsx/CustomStatusItem.tsx +++ b/components/SettingsUI.tsx/CustomStatusItem.tsx @@ -1,6 +1,6 @@ import { NoteStatus } from "@/types/noteStatus"; import { PluginSettings } from "@/types/pluginSettings"; -import React from "react"; +import React, { useState } from "react"; import { Input } from "@/components/atoms/Input"; export type Props = { @@ -21,35 +21,126 @@ export const CustomStatusItem: React.FC = ({ onCustomStatusChange, onCustomStatusRemove, }) => { + const [isHovered, setIsHovered] = useState(false); + const [focusedField, setFocusedField] = useState(null); + + const isValid = status.name.trim().length > 0; + const hasIcon = status.icon.trim().length > 0; + return ( -
+
setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + style={{ + background: "var(--background-secondary)", + border: `1px solid ${isValid ? "var(--background-modifier-border)" : "var(--background-modifier-error)"}`, + borderRadius: "var(--radius-m)", + padding: "var(--size-4-3)", + marginBottom: "var(--size-4-2)", + transition: "all 0.2s ease", + transform: isHovered ? "translateY(-1px)" : "translateY(0)", + boxShadow: isHovered ? "0 4px 12px rgba(0,0,0,0.1)" : "none", + }} + > + {/* Status Preview Bar */}
+ +
- - onCustomStatusChange(index, "icon", value || "❓") - } - placeholder="🔥" - className="custom-status-icon-input" - /> -
+ {/* Icon Input with Preview Circle */} +
+
+ {hasIcon ? status.icon : "?"} +
+ + onCustomStatusChange(index, "icon", value || "") + } + placeholder="🔥" + onFocus={() => setFocusedField("icon")} + onBlur={() => setFocusedField(null)} + style={{ + position: "absolute", + top: 0, + left: 0, + width: "48px", + height: "48px", + opacity: 0, + cursor: "pointer", + borderRadius: "50%", + }} + /> +
+ + {/* Text Inputs */} +
- onCustomStatusChange( - index, - "name", - value || "unnamed", - ) + onCustomStatusChange(index, "name", value || "") } placeholder="Status name" - className="custom-status-name-input" - style={{ color: status.color || "var(--text-normal)" }} + onFocus={() => setFocusedField("name")} + onBlur={() => setFocusedField(null)} + style={{ + background: "var(--background-primary)", + border: `1px solid ${ + focusedField === "name" + ? "var(--interactive-accent)" + : !isValid + ? "var(--background-modifier-error)" + : "var(--background-modifier-border)" + }`, + borderRadius: "var(--radius-s)", + padding: "var(--size-2-2) var(--size-2-3)", + fontSize: "var(--font-ui-medium)", + fontWeight: "var(--font-semibold)", + color: status.color || "var(--text-normal)", + transition: "border-color 0.2s ease", + }} /> = ({ onCustomStatusChange(index, "description", value) } placeholder="Description (optional)" - className="custom-status-description-input" + onFocus={() => setFocusedField("description")} + onBlur={() => setFocusedField(null)} + style={{ + background: "var(--background-primary)", + border: `1px solid ${ + focusedField === "description" + ? "var(--interactive-accent)" + : "var(--background-modifier-border)" + }`, + borderRadius: "var(--radius-s)", + padding: "var(--size-2-1) var(--size-2-3)", + fontSize: "var(--font-ui-small)", + color: "var(--text-muted)", + transition: "border-color 0.2s ease", + }} />
-
- - onCustomStatusChange(index, "color", value) - } - className="custom-status-color-input" - /> + + {/* Controls */} +
+ {/* Color Picker */} +
+ + onCustomStatusChange(index, "color", value) + } + onFocus={() => setFocusedField("color")} + onBlur={() => setFocusedField(null)} + style={{ + width: "40px", + height: "40px", + borderRadius: "var(--radius-s)", + border: `2px solid ${ + focusedField === "color" + ? "var(--interactive-accent)" + : "var(--background-modifier-border)" + }`, + cursor: "pointer", + transition: "border-color 0.2s ease", + }} + /> +
+ + {/* Remove Button */}
+ + {/* Validation Message */} + {!isValid && ( +
+ Status name is required +
+ )}
); }; diff --git a/styles/components/settings.css b/styles/components/settings.css index 341eb57..676accd 100644 --- a/styles/components/settings.css +++ b/styles/components/settings.css @@ -74,6 +74,8 @@ .custom-status-text-inputs { flex: 1; + display: flex; + flex-direction: column; } .custom-status-name-input {