Skip to content

Repository files navigation

@korekoi/react-tabler-flags

Tree-shakeable React components for the Tabler flags set — 287 flags (195 countries, 71 territories, 13 unions, 8 other), all 30×24 SVGs, one component per flag.

Built because @tabler/flags-react is effectively unmaintained: its latest publish is empty, it declares React as a hard dependency (which installs a nested React 18 and crashes on React 19), its size prop breaks on CSS lengths, and its styling is baked into the artwork. This package fixes all of that with a pipeline modelled on the same author's much more mature @tabler/icons-react.

  • React 18 and 19, react in peerDependencies only — never a nested copy.
  • Tree-shakeable: importing one flag costs ~1 KB min+gzip, not 571 KB.
  • Deep imports (@korekoi/react-tabler-flags/flags/FlagItaly) and a dynamic-import map for runtime lookup by country code.
  • Variants as props (rounded / square / circle), not baked artwork.
  • SSR-safe unique clip ids via useId, correct SVGSVGElement ref typing, displayName on every component, sensible a11y defaults.

Install

npm install @korekoi/react-tabler-flags

Requires React >= 18. No other dependencies.

Quick start

import { FlagItaly, FlagIT } from '@korekoi/react-tabler-flags'; // FlagIT === FlagItaly

<FlagItaly />                       // 24px tall, rounded, border + shine
<FlagItaly size={16} />             // 16px tall, 20px wide (5:4 kept)
<FlagItaly size="2rem" />           // 2rem tall, calc(2rem * 1.25) wide
<FlagItaly variant="square" shine={false} border={false} />  // bare artwork
<FlagItaly variant="circle" />      // square-cropped circle
<FlagItaly title="Italy" />         // accessible: <title> + role="img"

Props

Prop Type Default Notes
size number | string 24 Height. Width follows at 1.25× (1× for circle). Emitted as SVG attributes, so CSS always wins.
variant 'rounded' | 'square' | 'circle' 'rounded' rounded matches upstream @tabler/flags-react.
border boolean true Thin dark outline so light flags don't bleed into the background.
shine boolean true Subtle white top-edge highlight, matching upstream's look.
title string Renders <title> + role="img". Omit for decorative flags (aria-hidden is set automatically).
...rest SVGProps<SVGSVGElement> className, style, data-*, handlers, ref (typed SVGSVGElement) all pass through.

Every component keeps upstream's class names (tabler-flag, tabler-flag-italy), so CSS written against @tabler/flags-react@0.0.2 keeps working.

Deep imports

Each flag is its own published module:

import FlagItaly from '@korekoi/react-tabler-flags/flags/FlagItaly';
import FlagIT from '@korekoi/react-tabler-flags/flags/FlagIT'; // same module, re-exported

Two aliases exist only as root exports, not as deep imports: FlagNATO and FlagUN would collide with FlagNato/FlagUn on case-insensitive filesystems, so import those from the root (or deep-import the primary name).

Picking a flag at runtime

Don't resolve flags from the barrel at runtime — that bundles all 287. Use the dynamic map, which code-splits to one chunk per flag:

import { lazy, Suspense } from 'react';
import dynamicFlagImports, { dynamicFlagImportsByIso } from '@korekoi/react-tabler-flags/dynamic';

const CountryFlag = ({ iso }) => {
  const load = dynamicFlagImportsByIso[iso];
  if (!load) return null;
  const Flag = lazy(load);
  return (
    <Suspense fallback={null}>
      <Flag />
    </Suspense>
  );
};

(Memoize lazy(load) per code in real apps.)

Lists and metadata

import { flagsList, flagIsoToSlug } from '@korekoi/react-tabler-flags/list';
// [{ name: 'FlagItaly', alias: 'FlagIT', slug: 'italy', label: 'Italy',
//    category: 'Countries', iso: 'IT' }, ...]

FlagName, FlagSlug, FlagCategory and FlagProps types are exported from the root.

Tree-shaking notes

Named imports from the root are tree-shaken by every modern bundler (sideEffects: false + per-module ESM output). Importing the entire barrel (import * as flags) costs ≈570 KB uncompressed — that's all 287 flags and is unavoidable; prefer named imports or the dynamic map.

Sizing flags (and Tailwind)

Flags are not square — every flag is 30×24 (5:4). size sets the height; width follows automatically. Because size is emitted as SVG attributes (not inline styles), any CSS class you apply wins over it.

With Tailwind, size-* letterboxes a 5:4 flag inside a square. Use the bundled plugin instead, which mirrors the spacing scale at the correct ratio:

// tailwind.config.js (v3)
plugins: [require('@korekoi/react-tabler-flags/tailwind')],
/* app.css (v4) */
@plugin "@korekoi/react-tabler-flags/tailwind";
<FlagItaly className="flag-6" />                    // 24px tall, 30px wide
<FlagItaly className="flag-4 md:flag-8" />          // responsive variants work
<FlagItaly variant="circle" className="size-6" />   // circles ARE square — size-* is right here

Avoid h-6 w-auto: an <svg> with auto width fills its container instead of sizing from its ratio. The safe fluid direction is w-full h-auto.

Migrating from @tabler/flags-react@0.0.2

  • Export names are compatible (FlagIT, FlagUS, …) — imports are mostly mechanical. Flags without an ISO code use their full name (FlagChequered).
  • Delete any React overrides/resolutions hack — this package has no dependencies.
  • The default look matches upstream (rounded, border, shine).
  • size now accepts CSS lengths; numeric behaviour is unchanged.
  • Refs are now correctly typed as SVGSVGElement.

Development

npm run generate   # flags/*.svg + flags.json -> src/ (generated, gitignored)
npm test           # vitest: props matrix, regressions, 287 snapshots, typecheck
npm run build      # rollup esm/cjs + d.ts/d.cts, then structural verification
npm run attw       # arethetypeswrong against the packed tarball
npm run size       # size budget check
npm run smoke      # pack + clean install against React 18 and 19 + SSR render
npm run sync-upstream  # refresh vendored artwork from tabler/tabler-flags
npm run demo       # build demo/index.html with all 287 flags

There's a full integration fixture in examples/vite-tailwind — a Vite + React 19 + Tailwind v4 app installed from the packed tarball:

npm run example:refresh  # build + pack + install the library into the example
npm run example:dev      # play with it locally
npm run example:verify   # bundle assertions + headless Chrome checks (runs in CI)

License and attribution

MIT. Flag artwork is from tabler/tabler-flags and the build pipeline is derived from tabler/tabler-icons, both MIT © Paweł Kuna — see NOTICE. This project is not affiliated with or endorsed by Tabler.

About

Tabler Flags for React

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages