mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-24 13:52:45 +00:00
Addition of FlagInputModal (#1606)
## Description: The UI for selecting flags differs from other existing UIs, so this change allows it to use . The actual contents for flag selection will be included in the next PR. ## 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 - [x] I have read and accepted the CLA agreement (only required once). ## Please put your Discord username so you can be contacted if a bug or regression is found: aotumuri --------- Co-authored-by: Scott Anderson <662325+scottanderson@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
import { LitElement, html } from "lit";
|
||||
import { customElement, query, state } from "lit/decorators.js";
|
||||
import Countries from "./data/countries.json";
|
||||
|
||||
@customElement("flag-input-modal")
|
||||
export class FlagInputModal extends LitElement {
|
||||
@query("o-modal") private modalEl!: HTMLElement & {
|
||||
open: () => void;
|
||||
close: () => void;
|
||||
};
|
||||
|
||||
@state() private search: string = "";
|
||||
|
||||
createRenderRoot() {
|
||||
return this;
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<o-modal title="Flag Selector Modal" alwaysMaximized>
|
||||
<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 h-[90%]"
|
||||
>
|
||||
${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);
|
||||
this.close();
|
||||
}}
|
||||
class="text-center cursor-pointer border-none bg-none opacity-70
|
||||
w-[calc(100%/2-15px)] sm:w-[calc(100%/4-15px)]
|
||||
md:w-[calc(100%/6-15px)] lg:w-[calc(100%/8-15px)]
|
||||
xl:w-[calc(100%/10-15px)] min-w-[80px]"
|
||||
>
|
||||
<img
|
||||
class="country-flag w-full h-auto"
|
||||
src="/flags/${country.code}.svg"
|
||||
@error=${(e: Event) => {
|
||||
const img = e.currentTarget as HTMLImageElement;
|
||||
const fallback = "/flags/xx.svg";
|
||||
if (img.src && !img.src.endsWith(fallback)) {
|
||||
img.src = fallback;
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<span class="country-name">${country.name}</span>
|
||||
</button>
|
||||
`,
|
||||
)}
|
||||
</div>
|
||||
</o-modal>
|
||||
`;
|
||||
}
|
||||
|
||||
private handleSearch(event: Event) {
|
||||
this.search = (event.target as HTMLInputElement).value;
|
||||
}
|
||||
|
||||
private setFlag(flag: string) {
|
||||
localStorage.setItem("flag", flag);
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("flag-change", {
|
||||
detail: { flag },
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
public open() {
|
||||
this.modalEl?.open();
|
||||
}
|
||||
public close() {
|
||||
this.modalEl?.close();
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
window.addEventListener("keydown", this.handleKeyDown);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
window.removeEventListener("keydown", this.handleKeyDown);
|
||||
super.disconnectedCallback();
|
||||
}
|
||||
|
||||
private handleKeyDown = (e: KeyboardEvent) => {
|
||||
if (e.code === "Escape") {
|
||||
e.preventDefault();
|
||||
this.close();
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user