mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-26 06:32:43 +00:00
141 lines
4.2 KiB
TypeScript
141 lines
4.2 KiB
TypeScript
import { LitElement, css, html } from "lit";
|
|
import { customElement, state } from "lit/decorators.js";
|
|
import Countries from "./data/countries.json";
|
|
const flagKey: string = "flag";
|
|
|
|
@customElement("flag-input")
|
|
export class FlagInput extends LitElement {
|
|
@state() private flag: string = "";
|
|
@state() private search: string = "";
|
|
@state() private showModal: boolean = false;
|
|
|
|
static styles = css`
|
|
@media (max-width: 768px) {
|
|
.flag-modal {
|
|
width: 80vw;
|
|
}
|
|
|
|
.dropdown-item {
|
|
width: calc(100% / 3 - 15px);
|
|
}
|
|
}
|
|
`;
|
|
|
|
private handleSearch(e: Event) {
|
|
this.search = String((e.target as HTMLInputElement).value);
|
|
}
|
|
|
|
private setFlag(flag: string) {
|
|
if (flag == "xx") {
|
|
flag = "";
|
|
}
|
|
this.flag = flag;
|
|
this.showModal = false;
|
|
this.storeFlag(flag);
|
|
}
|
|
|
|
public getCurrentFlag(): string {
|
|
return this.flag;
|
|
}
|
|
|
|
private getStoredFlag(): string {
|
|
const storedFlag = localStorage.getItem(flagKey);
|
|
if (storedFlag) {
|
|
return storedFlag;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
private storeFlag(flag: string) {
|
|
if (flag) {
|
|
localStorage.setItem(flagKey, flag);
|
|
} else if (flag === "") {
|
|
localStorage.removeItem(flagKey);
|
|
}
|
|
}
|
|
|
|
private dispatchFlagEvent() {
|
|
this.dispatchEvent(
|
|
new CustomEvent("flag-change", {
|
|
detail: { flag: this.flag },
|
|
bubbles: true,
|
|
composed: true,
|
|
}),
|
|
);
|
|
}
|
|
|
|
connectedCallback() {
|
|
super.connectedCallback();
|
|
this.flag = this.getStoredFlag();
|
|
this.dispatchFlagEvent();
|
|
}
|
|
|
|
createRenderRoot() {
|
|
return this;
|
|
}
|
|
|
|
render() {
|
|
return html`
|
|
<div
|
|
class="absolute left-0 top-0 w-full h-full ${this.showModal
|
|
? ""
|
|
: "hidden"}"
|
|
@click=${() => (this.showModal = false)}
|
|
></div>
|
|
<div class="flex relative">
|
|
<button
|
|
@click=${() => (this.showModal = !this.showModal)}
|
|
class="border p-[4px] rounded-lg flex cursor-pointer border-black/30 dark:border-gray-300/60 bg-white/70 dark:bg-[rgba(55,65,81,0.7)]"
|
|
title="Pick a flag!"
|
|
>
|
|
<img class="size-[48px]" src="/flags/${this.flag || "xx"}.svg" />
|
|
</button>
|
|
${this.showModal
|
|
? html`
|
|
<div
|
|
class="text-white flex flex-col gap-[0.5rem] absolute top-[60px] left-[0px] w-[780%] h-[500px] max-h-[50vh] max-w-[87vw] bg-gray-900/80 backdrop-blur-md p-[10px] rounded-[8px] z-[3] ${this
|
|
.showModal
|
|
? ""
|
|
: "hidden"}"
|
|
>
|
|
<input
|
|
class="h-[2rem] border-none text-center border border-gray-300 rounded-xl shadow-sm text-2xl text-center focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-black dark:border-gray-300/60 dark:bg-gray-700 dark:text-white"
|
|
type="text"
|
|
placeholder="Search..."
|
|
@change=${this.handleSearch}
|
|
@keyup=${this.handleSearch}
|
|
/>
|
|
<div
|
|
class="flex flex-wrap justify-evenly gap-[1rem] overflow-y-auto overflow-x-hidden"
|
|
>
|
|
${Countries.filter(
|
|
(country) =>
|
|
country.name
|
|
.toLowerCase()
|
|
.includes(this.search.toLowerCase()) ||
|
|
country.code
|
|
.toLowerCase()
|
|
.includes(this.search.toLowerCase()),
|
|
).map(
|
|
(country) => html`
|
|
<button
|
|
@click=${() => this.setFlag(country.code)}
|
|
class="text-center cursor-pointer border-none bg-none opacity-70 sm:w-[calc(33.3333%-15px) w-[calc(100%/3-15px)] md:w-[calc(100%/4-15px)]"
|
|
>
|
|
<img
|
|
class="country-flag w-full h-auto"
|
|
src="/flags/${country.code}.svg"
|
|
/>
|
|
<span class="country-name">${country.name}</span>
|
|
</button>
|
|
`,
|
|
)}
|
|
</div>
|
|
</div>
|
|
`
|
|
: ""}
|
|
</div>
|
|
`;
|
|
}
|
|
}
|