UNPKG

solid-circle-flags

Version:

A Solid component with a collection of 300+ minimal circular SVG country flags.

348 lines (342 loc) 6.87 kB
import { createComponent, mergeProps, memo, spread, effect, setAttribute, template } from 'solid-js/web'; import { createSignal } from 'solid-js'; // src/index.tsx // src/countries.ts var countryToCountryMap = { ac: "sh-ac", bq: "bq-bo", bv: "no", "cn-hk": "hk", cp: "fr-cp", dg: "io", ea: "es-ce", eu: "european_union", fx: "fr", hm: "au", ic: "es-cn", sh: "sh-hl", sj: "no", su: "soviet_union", ta: "sh-ta", uk: "gb", um: "us", "us-as": "as", "us-gu": "gu", "us-mp": "mp", "us-pr": "pr", "us-um": "us", "us-vi": "vi" }; // src/languages.ts var languageToCountryMap = { aa: "et-af", ab: "ge-ab", af: "za", ak: "gh", am: "et", an: "es-ar", as: "in-as", av: "ru-da", ay: "bo", az: "az", ba: "ru-ba", be: "by", bg: "bg", bi: "vu", bm: "ml", bn: "bd", bo: "tibet", br: "fr-bre", bs: "ba", ca: "es-ct", ce: "ru-ce", ceb: "ph", ch: "gu", chm: "ru", ckb: "iq-kr", co: "fr-20r", cs: "cz", cv: "ru-cu", cy: "gb-wls", da: "dk", de: "de", dv: "mv", dz: "bt", ee: "gh", el: "gr", en: "us", es: "es", et: "ee", eu: "es-pv", fa: "ir", fi: "fi", fil: "ph", fj: "fj", fo: "fo", fr: "fr", fy: "nl-fr", ga: "ie", gd: "gb-sct", gl: "es-ga", gn: "py", gu: "in-gj", gv: "im", ha: "ng", haw: "us-hi", he: "il", hi: "in", hmn: "hmong", ho: "pg", hr: "hr", ht: "ht", hu: "hu", hy: "am", id: "id", ig: "ng", ilo: "ph", is: "is", it: "it", ja: "jp", jv: "id-jt", ka: "ge", kg: "cd", ki: "ke", kk: "kz", kl: "gl", km: "kh", kn: "in-ka", ko: "kr", kr: "ng", kri: "sl", ks: "in", ku: "iq-kr", kv: "ru-ko", kw: "gb-con", ky: "kg", lb: "lu", lg: "ug", ln: "cd", lo: "la", lt: "lt", lu: "cd", lus: "in-mz", lv: "lv", mg: "mg", mh: "mh", mi: "maori", mk: "mk", ml: "malayali", mn: "mn", mni: "in-mn", mrj: "ru", ms: "my", mt: "mt", my: "mm", na: "nr", nb: "no", nd: "zw", ne: "np", nl: "nl", nn: "no", no: "no", nr: "za", ny: "mw", oc: "occitania", om: "et", or: "in-or", os: "ru", oto: "mx", pa: "in", pap: "cw", pl: "pl", pms: "it-21", ps: "af", "pt-br": "br", pt: "pt", qu: "pe", rm: "ch-gr", rn: "bi", ro: "ro", ru: "ru", rw: "rw", sc: "it-82", sd: "pk-sd", se: "no", sg: "cf", si: "lk", sk: "sk", sl: "si", sm: "ws", sn: "zw", so: "so", sq: "al", sr: "rs", ss: "sz", st: "ls", su: "id-jb", sv: "se", sw: "tz", ta: "in-tn", te: "in-tg", tg: "tj", th: "th", ti: "er", tk: "tm", tl: "ph", tn: "bw", to: "to", tr: "tr", tt: "ru-ta", ty: "pf", udm: "ru-ud", ug: "cn-xj", uk: "ua", ur: "pk", uz: "uz", vi: "vn", xh: "za", yo: "yorubaland", yua: "mx", zh: "cn", zu: "za" }; var _tmpl$ = /* @__PURE__ */ template(`<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 512 512"aria-label=Loading role=img><mask id=circular-graphic-fallback-mask><circle cx=256 cy=256 r=256 fill=#fff></circle></mask><g mask=url(#circular-graphic-fallback-mask)><path fill=#eee d="M0 0h512v512H0z"></path><circle cx=253 cy=380 r=32 fill=#acabb1></circle><path fill=#acabb1 d="M322.4 135.5c-15.6-13.6-37.4-20.3-65.5-20.3-27.9 0-49.9 7.2-66 21.4a74.9 74.9 0 0 0-24.3 55.4h-.2v12.8H224l.1-9a35.2 35.2 0 0 1 9.3-24.8c5.8-6.1 13.7-9 23.5-9 20.7 0 31 11 31 33.4 0 7.4-2 14.5-6 21.1a124.2 124.2 0 0 1-23.9 26 90.4 90.4 0 0 0-24.8 32.3c-4.5 11-6.8 26.7-6.8 45.2h51l.8-13.1a54 54 0 0 1 17.3-33.9l16.2-15.2a131.4 131.4 0 0 0 26.4-33.2 69.5 69.5 0 0 0 7.6-31.8c-.1-24.7-7.8-43.7-23.3-57.3z">`); function FallbackSvg(props) { return (() => { var _el$ = _tmpl$(), _el$2 = _el$.firstChild; _el$2.nextSibling; effect((_p$) => { var _v$ = props.width, _v$2 = props.height; _v$ !== _p$.e && setAttribute(_el$, "width", _p$.e = _v$); _v$2 !== _p$.t && setAttribute(_el$, "height", _p$.t = _v$2); return _p$; }, { e: void 0, t: void 0 }); return _el$; })(); } var _tmpl$2 = /* @__PURE__ */ template(`<img>`); var DEFAULT_CDN_URLS = { country: "https://circle-flags.zeljko.me/flags/", language: "https://circle-flags.zeljko.me/flags/language/" }; var ENV_CDN_URL = import.meta.env.VITE_PUBLIC_CIRCLE_FLAGS_CDN_URL?.trim() || ""; function CircularGraphic(props) { const { code, type, cdn, label, width, height, alt, src, onError, ...restProps } = props; const [imgError, setImgError] = createSignal(false); const getCdnUrl = () => { const rawCdn = props.cdn?.trim() || ENV_CDN_URL || DEFAULT_CDN_URLS[props.type]; return rawCdn.replace(/\/+$/, "") + "/"; }; const getCleanCode = () => { return props.code.replace(/^\/+/, ""); }; const getSourceUrl = () => { return `${getCdnUrl()}${getCleanCode()}.svg`; }; const getAriaLabel = () => { return props.label || `${props.type} ${getCleanCode()} flag`; }; const handleError = () => { setImgError(true); }; return memo(() => memo(() => !!!imgError())() ? (() => { var _el$ = _tmpl$2(); _el$.addEventListener("error", handleError); spread(_el$, mergeProps({ get src() { return getSourceUrl(); }, get width() { return props.width; }, get height() { return props.height; }, get alt() { return getAriaLabel(); } }, restProps), false, false); return _el$; })() : createComponent(FallbackSvg, { get width() { return props.width; }, get height() { return props.height; } })); } // src/index.tsx function CircleFlag(props) { const { countryCode, width, height, cdn, label, ...imgProps } = props; const mappedCountryCode = countryToCountryMap[countryCode]; if (mappedCountryCode !== void 0) { return createComponent(CircularGraphic, mergeProps({ code: mappedCountryCode, type: "country", width, height, cdn, label }, imgProps)); } else { return createComponent(CircularGraphic, mergeProps({ code: countryCode, type: "country", width, height, cdn, label }, imgProps)); } } function CircleFlagLanguage(props) { const { languageCode, width, height, cdn, label, ...imgProps } = props; const mappedCountryCode = languageToCountryMap[languageCode]; if (mappedCountryCode !== void 0) { return createComponent(CircleFlag, mergeProps({ countryCode: mappedCountryCode, width, height, cdn, label }, imgProps)); } else { return createComponent(CircularGraphic, mergeProps({ code: languageCode, type: "language", width, height, cdn, label }, imgProps)); } } export { CircleFlag, CircleFlagLanguage };