Skip to content
Docs version
@hungpvq/vue-map@1.1.0@hungpvq/vue-map-core@1.1.0@hungpvq/vue-map-dataset@1.1.0@hungpvq/vue-map-draw@1.1.0@hungpvq/map-draw@1.1.0@hungpvq/react-map@1.1.0@hungpvq/react-map-core@1.1.0@hungpvq/react-map-dataset@1.1.0@hungpvq/react-map-draw@1.1.0

LanguageControl

Usecase

  • Switch map UI language (en / vi by default; any string code).
  • Collapsed face always shows the active language code (VI, EN, …).
  • Hover expands like ThemeControl: language chips + current face (fr | vi | en | <current> visually on right corners).
  • Click a chip to select that language; click <current> to cycle the next code in languages.
  • Optional API loader merges flat or nested JSON into the active catalog.

Built-in packs: MAP_CORE_LOCALE_EN / MAP_CORE_LOCALE_VI. Pass dataset/draw packs via locales.en / locales.vi. Preference is stored under localStorage key hungpvq.map-language.

Props

PropTypeDefaultDescription
labelsRecord<string, string>Tooltip titles (chips still show uppercase codes EN / VI)
languagesstring[]['en','vi']Codes shown as text chips (e.g. ['en','vi','fr'])
defaultLanguagestring'vi'Used when nothing stored / stored code not in languages
fallbackLanguagestring'en' store defaultCatalog used when a key is missing
localeLoader(lang) => Promise<flat | nested>Fetch on mount (initial) and when selecting a language
reloadOnSelectbooleanfalseForce re-fetch on every select
translateMapTranslateFunction | nullExternal i18n ((key, params, fallback) => string); null clears
PropDescriptionTypeRequiredDefault Value
mapIdstringfalse--
dragIdstringfalse--
btnWidthnumberfalse40
controlOrderCSS flex order for the standalone buttonnumberfalse0
position'top-left', 'top-right', 'bottom-left', 'bottom-right'false'bottom-right'
controlLayout'standalone' (corner), 'toolbar' (always in toolbar), 'button' (always corner; not auto-promoted on mobile)'standalone' | 'toolbar' | 'button'false'standalone'
controlVisiblebooleanfalsetrue

Map also accepts buttonInMobile ('button' | 'toolbar' | 'menu', default 'button'). On viewports ≤640px:

  • 'button' — leave corner buttons unchanged
  • 'toolbar' — move declared control buttons into a single ToolbarControl host (except controlLayout="button"). Mount one ToolbarControl in the map slot
  • 'menu' — hide per-control corner buttons; fan out intact clusters by position into corner stacks with outside-in More. Mount one ToolbarControl.

See ToolbarControl.

Examples

Vue

vue
<script setup lang="ts">
import { deepMergeLocale } from '@hungpvq/map-core';
import { MAP_DATASET_LOCALE_VI } from '@hungpvq/map-dataset';
import { LanguageControl, Map, HomeControl } from '@hungpvq/vue-map-core';

async function localeLoader(lang: string) {
  const res = await fetch(`/demo-i18n/${lang}.json`);
  return res.ok ? res.json() : null;
}
</script>

<template>
  <Map>
    <LanguageControl
      default-language="vi"
      :locales="{ vi: MAP_DATASET_LOCALE_VI }"
      :locale-loader="localeLoader"
    />
    <HomeControl />
  </Map>
</template>

React

tsx
import { LanguageControl, Map, HomeControl } from '@hungpvq/react-map-core';
import { MAP_DATASET_LOCALE_VI } from '@hungpvq/map-dataset';

<Map>
  <LanguageControl
    defaultLanguage="vi"
    locales={{ vi: MAP_DATASET_LOCALE_VI }}
    localeLoader={async (lang) => {
      const res = await fetch(`/demo-i18n/${lang}.json`);
      return res.ok ? res.json() : null;
    }}
  />
  <HomeControl />
</Map>

Demo: /#/language (Vue & React demo-map).

  • Extra LangregisterLocale, loadLocale, override & add languages
  • Registry id: mapLanguageControl