Some checks failed
CI / style (push) Has been cancelled
CI / build-client (push) Has been cancelled
CI / build-amd64 (push) Has been cancelled
CI / build-tester (push) Has been cancelled
CI / test (cockroachdb) (push) Has been cancelled
CI / test (mariadb) (push) Has been cancelled
CI / test (postgres) (push) Has been cancelled
CI / test (sqlite) (push) Has been cancelled
CI / build-arm64 (push) Has been cancelled
CI / build-armv7 (push) Has been cancelled
CI / publish-images (push) Has been cancelled
CI / publish-release (push) Has been cancelled
Enhances SpoolIcon component with optional showHex prop: - Displays hex color code next to swatch when enabled - Click to copy hex code to clipboard - Shows tooltip with copy hint - Supports both single and multi-color filaments Enabled on detail pages: - Filament show page - Spool show page Added translation keys for copy feedback messages. Closes #33 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
73 lines
2.1 KiB
TypeScript
73 lines
2.1 KiB
TypeScript
import { CopyOutlined } from "@ant-design/icons";
|
|
import { message, Tooltip } from "antd";
|
|
import { useTranslate } from "@refinedev/core";
|
|
import "./spoolIcon.css";
|
|
|
|
interface Props {
|
|
color: string | { colors: string[]; vertical: boolean };
|
|
size?: "small" | "large";
|
|
no_margin?: boolean;
|
|
showHex?: boolean;
|
|
}
|
|
|
|
export default function SpoolIcon(props: Readonly<Props>) {
|
|
const t = useTranslate();
|
|
let dirClass = "vertical";
|
|
let cols: string[] = [];
|
|
const size = props.size ? props.size : "small";
|
|
const no_margin = props.no_margin ? "no-margin" : "";
|
|
|
|
if (typeof props.color === "string") {
|
|
cols = [props.color];
|
|
} else {
|
|
dirClass = props.color.vertical ? "vertical" : "horizontal";
|
|
cols = props.color.colors;
|
|
}
|
|
|
|
// Normalize hex codes (remove # if present, uppercase)
|
|
const normalizedCols = cols.map((col) => col.replace("#", "").toUpperCase());
|
|
const hexDisplay = normalizedCols.length === 1 ? `#${normalizedCols[0]}` : normalizedCols.map((c) => `#${c}`).join(", ");
|
|
|
|
const copyToClipboard = async () => {
|
|
try {
|
|
await navigator.clipboard.writeText(hexDisplay);
|
|
message.success(t("color.copied", { color: hexDisplay }));
|
|
} catch {
|
|
message.error(t("color.copy_failed"));
|
|
}
|
|
};
|
|
|
|
const swatchContent = (
|
|
<div className={"spool-icon " + dirClass + " " + size + " " + no_margin}>
|
|
{normalizedCols.map((col) => (
|
|
<div
|
|
key={col}
|
|
style={{
|
|
backgroundColor: "#" + col,
|
|
}}
|
|
></div>
|
|
))}
|
|
</div>
|
|
);
|
|
|
|
if (props.showHex) {
|
|
return (
|
|
<Tooltip title={`${t("color.click_to_copy")}: ${hexDisplay}`}>
|
|
<div
|
|
className="spool-icon-with-hex"
|
|
onClick={copyToClipboard}
|
|
style={{ cursor: "pointer", display: "inline-flex", alignItems: "center", gap: 8 }}
|
|
>
|
|
{swatchContent}
|
|
<span className="hex-code" style={{ fontFamily: "monospace", fontSize: "0.85em", opacity: 0.8 }}>
|
|
{hexDisplay}
|
|
<CopyOutlined style={{ marginLeft: 4, fontSize: "0.9em" }} />
|
|
</span>
|
|
</div>
|
|
</Tooltip>
|
|
);
|
|
}
|
|
|
|
return swatchContent;
|
|
}
|