mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-13 22:59:02 +00:00
standardize UI colors to fit brand guidelines (#3754)
## Description: We have brand colors: <img width="738" height="900" alt="Screenshot 2026-04-25 at 12 52 29 PM" src="https://github.com/user-attachments/assets/aac69e87-91f2-4c3f-9f1e-f69f48f5943e" /> So update the homepage & in-game UI to use those colors: <img width="1185" height="946" alt="Screenshot 2026-04-25 at 12 51 06 PM" src="https://github.com/user-attachments/assets/89a0b12c-2db1-43d4-9500-fcf405c0f7ff" /> Also updated buttons to use the o-button element ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced ## Please put your Discord username so you can be contacted if a bug or regression is found: evan
This commit is contained in:
@@ -1,51 +1,99 @@
|
||||
import { LitElement, html } from "lit";
|
||||
import { LitElement, TemplateResult, html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { classMap } from "lit/directives/class-map.js";
|
||||
import { translateText } from "../../Utils";
|
||||
|
||||
type ButtonVariant = "primary" | "secondary" | "danger" | "ghost";
|
||||
type ButtonSize = "sm" | "md" | "lg";
|
||||
type ButtonWidth = "auto" | "block" | "blockDesktop" | "fill";
|
||||
type IconPosition = "left" | "right" | "only";
|
||||
|
||||
@customElement("o-button")
|
||||
export class OButton extends LitElement {
|
||||
@property({ type: String }) title = "";
|
||||
@property({ type: String }) translationKey = "";
|
||||
@property({ type: Boolean }) secondary = false;
|
||||
@property({ type: Boolean }) block = false;
|
||||
@property({ type: Boolean }) blockDesktop = false;
|
||||
@property() title = "";
|
||||
@property() translationKey = "";
|
||||
@property() variant: ButtonVariant = "primary";
|
||||
@property() size: ButtonSize = "md";
|
||||
@property() width: ButtonWidth = "auto";
|
||||
@property() iconPosition: IconPosition = "left";
|
||||
@property({ attribute: false }) icon?: TemplateResult;
|
||||
@property({ type: Boolean }) disable = false;
|
||||
@property({ type: Boolean }) fill = false;
|
||||
@property({ type: Boolean }) submit = false;
|
||||
private static readonly BASE_CLASS =
|
||||
"bg-[#0073b7] hover:bg-sky-700 text-white font-bold uppercase tracking-wider px-4 py-3 rounded-xl transition-all duration-300 transform hover:-translate-y-px outline-none border border-transparent text-center text-base lg:text-lg whitespace-normal break-words leading-tight overflow-hidden relative";
|
||||
|
||||
createRenderRoot() {
|
||||
return this;
|
||||
}
|
||||
|
||||
private getButtonClasses(): Record<string, boolean> {
|
||||
return {
|
||||
[OButton.BASE_CLASS]: true,
|
||||
"w-full block": this.block,
|
||||
"h-full w-full flex items-center justify-center": this.fill,
|
||||
"lg:w-auto lg:inline-block":
|
||||
!this.block && !this.blockDesktop && !this.fill,
|
||||
"lg:w-1/2 lg:mx-auto lg:block": this.blockDesktop,
|
||||
"bg-gray-700 text-gray-100 hover:bg-gray-600": this.secondary,
|
||||
"disabled:opacity-70 disabled:cursor-not-allowed disabled:transform-none disabled:bg-gray-600":
|
||||
this.disable,
|
||||
};
|
||||
private readonly BASE =
|
||||
"font-bold uppercase tracking-wider rounded-xl border border-transparent " +
|
||||
"transition-all duration-300 transform hover:-translate-y-px " +
|
||||
"outline-none text-center whitespace-normal break-words leading-tight overflow-hidden relative " +
|
||||
"disabled:cursor-not-allowed disabled:hover:translate-y-0 disabled:opacity-70";
|
||||
|
||||
private variantClasses(): string {
|
||||
switch (this.variant) {
|
||||
case "primary":
|
||||
return "bg-malibu-blue hover:bg-aquarius text-white disabled:bg-gray-600 disabled:text-gray-300";
|
||||
case "secondary":
|
||||
return "bg-gray-700 hover:bg-gray-600 text-white disabled:bg-gray-800 disabled:text-gray-400";
|
||||
case "danger":
|
||||
return "bg-red-600 hover:bg-red-500 text-white disabled:bg-red-900 disabled:text-gray-300";
|
||||
case "ghost":
|
||||
return "bg-transparent hover:bg-white/10 text-malibu-blue disabled:text-gray-500 disabled:hover:bg-transparent";
|
||||
}
|
||||
}
|
||||
|
||||
private sizeClasses(): string {
|
||||
if (this.iconPosition === "only") {
|
||||
switch (this.size) {
|
||||
case "sm":
|
||||
return "w-8 h-8 text-sm";
|
||||
case "md":
|
||||
return "w-10 h-10 text-base";
|
||||
case "lg":
|
||||
return "w-12 h-12 text-lg";
|
||||
}
|
||||
}
|
||||
switch (this.size) {
|
||||
case "sm":
|
||||
return "py-1.5 px-3 text-sm";
|
||||
case "md":
|
||||
return "py-3 px-4 text-base lg:text-lg";
|
||||
case "lg":
|
||||
return "py-4 px-6 text-lg lg:text-xl";
|
||||
}
|
||||
}
|
||||
|
||||
private widthClasses(): string {
|
||||
switch (this.width) {
|
||||
case "auto":
|
||||
return "inline-flex items-center justify-center gap-2";
|
||||
case "block":
|
||||
return "flex w-full items-center justify-center gap-2";
|
||||
case "blockDesktop":
|
||||
return "flex w-full items-center justify-center gap-2 lg:w-1/2 lg:mx-auto";
|
||||
case "fill":
|
||||
return "flex w-full h-full items-center justify-center gap-2";
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const label =
|
||||
this.translationKey === ""
|
||||
? this.title
|
||||
: translateText(this.translationKey);
|
||||
const iconOnly = this.iconPosition === "only";
|
||||
const classes = `${this.BASE} ${this.variantClasses()} ${this.sizeClasses()} ${this.widthClasses()}`;
|
||||
|
||||
return html`
|
||||
<button
|
||||
class=${classMap(this.getButtonClasses())}
|
||||
class=${classes}
|
||||
?disabled=${this.disable}
|
||||
type=${this.submit ? "submit" : "button"}
|
||||
aria-label=${iconOnly ? label : nothing}
|
||||
>
|
||||
<span class="block min-w-0">
|
||||
${this.translationKey === ""
|
||||
? this.title
|
||||
: translateText(this.translationKey)}
|
||||
</span>
|
||||
${this.icon && this.iconPosition !== "right" ? this.icon : nothing}
|
||||
${iconOnly ? nothing : html`<span class="min-w-0">${label}</span>`}
|
||||
${this.icon && this.iconPosition === "right" ? this.icon : nothing}
|
||||
</button>
|
||||
`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user