@maz-ui/mcp 5.0.0-beta.50 → 5.0.0-beta.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mcp.mjs CHANGED
@@ -7,7 +7,7 @@ import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
7
7
  import { resolve, join, dirname } from 'node:path';
8
8
  import { fileURLToPath } from 'node:url';
9
9
 
10
- const version = "5.0.0-beta.49";
10
+ const version = "5.0.0-beta.50";
11
11
 
12
12
  class MetadataExtractor {
13
13
  extract(name, type, content, manualTags = []) {
@@ -1,47 +1,48 @@
1
1
  ## Props
2
2
 
3
- | Name | Description | Type | Required | Default | Possible values |
4
- | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
5
- | **style** | Style attribut of the component root element | `HTMLAttributes['style']` | No | `undefined` | - |
6
- | **class** | Class attribut of the component root element | `HTMLAttributes['class']` | No | `undefined` | - |
7
- | **model-value** | `v-model` <br/>The current value of the input field in international format (e.g. +33612345678)<br/>**Example:** `"+33612345678"` | `string \| undefined \| null` | No | `undefined` | - |
8
- | **country-code** | `v-model:country-code` <br/>The selected country code (e.g. "FR")<br/>**Example:** `"FR"` | `CountryCode \| undefined \| null` | No | `undefined` | - |
9
- | **id** | Unique identifier for the component<br/>**Example:** `"phone-input-1"` | `string` | No | `undefined` | - |
10
- | **placeholder** | Text displayed when the input is empty<br/>**Example:** `"Enter your phone number"` | `string` | No | `undefined` | - |
11
- | **top-label** | Static label displayed above the input field. Unlike the floating label, this remains fixed<br/>**Example:** `"User Information"` | `string` | No | `undefined` | - |
12
- | **label** | Label displayed above the input<br/>**Example:** `"Phone Number"` | `string` | No | `undefined` | - |
13
- | **preferred-countries** | List of country codes to place first in the select list<br/>**Example:** `["FR", "BE", "GE"]` | `CountryCode[]` | No | `undefined` | - |
14
- | **ignored-countries** | List of country codes to be removed from the select list<br/>**Example:** `["FR", "BE", "GE"]` | `CountryCode[]` | No | `undefined` | - |
15
- | **only-countries** | List of country codes to only have the countries selected in the select list<br/>**Example:** `["FR", "BE", "GE"]` | `CountryCode[]` | No | `undefined` | - |
16
- | **translations** | Locale strings of the component The default values are the translations of the MazUiTranslations plugin | `Partial<MazUiTranslationsNestedSchema['inputPhoneNumber']>` | No | `{ countrySelect: { error: 'Choose country', placeholder: 'Country code', searchPlaceholder: 'Search the country', }, phoneInput: { placeholder: 'Phone number', example: 'Example: {example}', }, }` | - |
17
- | **list-position** | Position where the list of countries will be opened | `MazPopoverProps['position']` | No | `bottom left` | `top left, top right, bottom left, bottom right` |
18
- | **color** | Component color applied | `MazColor` | No | `primary` | `primary, secondary, accent, info, success, warning, destructive, contrast` |
19
- | **size** | Component size applied | `MazSize` | No | `md` | `xs, sm, md, lg, xl, mini` |
20
- | **hide-flags** | Remove flags in country list | `boolean` | No | `false` | - |
21
- | **disabled** | Make the input disabled | `boolean` | No | `false` | - |
22
- | **required** | Make the input required | `boolean` | No | `false` | - |
23
- | **example** | Show the phone number example | `boolean` | No | `true` | - |
24
- | **search** | Disable search input in country list | `boolean` | No | `true` | - |
25
- | **search-threshold** | Threshold of the search input in country list where 1 is a perfect match and 0 is a match with any character | `number` | No | `0.75` | - |
26
- | **use-browser-locale** | If true, the browser locale will be used | `boolean` | No | `true` | - |
27
- | **fetch-country** | The component will make a request (https://ipwho.is) to get the location of the user and use it to set the default country code | `boolean` | No | `false` | - |
28
- | **hide-country-select** | Hide the country selector | `boolean` | No | `false` | - |
29
- | **show-code-in-list** | Show country calling code in the country list | `boolean` | No | `false` | - |
30
- | **custom-countries-list** | Replace country names | `Record<CountryCode, string>` | No | `undefined` | - |
31
- | **auto-format** | Disabled auto-format when phone is valid | `"blur" \| "typing" \| "disabled" \| false` | No | `blur` | - |
32
- | **country-locale** | Locale of country list<br/>**Example:** `"fr-FR"` | `string` | No | `undefined` | - |
33
- | **validation-error** | Disable validation error UI | `boolean` | No | `true` | - |
34
- | **validation-success** | Disable validation success UI | `boolean` | No | `true` | - |
35
- | **success** | Add success UI | `boolean` | No | `false` | - |
36
- | **error** | Add error UI | `boolean` | No | `false` | - |
37
- | **warning** | Add warning UI | `boolean` | No | `false` | - |
38
- | **display-country-name** | Will replace the calling code by the country name in the country selector | `boolean` | No | `false` | - |
39
- | **block** | The input will be displayed in full width | `boolean` | No | `false` | - |
40
- | **orientation** | Orientation of the inputs in the component | `'row' \| 'col' \| 'responsive'` | No | `responsive` | `row, col, responsive` |
41
- | **country-select-attributes** | Meta attributes of the country input | `Record<string, unknown>` | No | `{ autocomplete: 'off', name: 'country' }` | - |
42
- | **phone-input-attributes** | Meta attributes of the phone number input | `Record<string, unknown>` | No | `{ autocomplete: 'tel', name: 'phone', inputmode: 'tel' }` | - |
43
- | **assistive-text** | Helper text displayed below the input to provide additional context or validation feedback<br/>**Example:** `"Must contain at least 8 characters"` | `string` | No | `undefined` | - |
44
- | **hint** | Alternative text that replaces the label when provided. Useful for contextual hints<br/>**Example:** `"This phone number is not valid"` | `string` | No | `undefined` | - |
3
+ | Name | Description | Type | Required | Default | Possible values |
4
+ | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
5
+ | **style** | Style attribut of the component root element | `HTMLAttributes['style']` | No | `undefined` | - |
6
+ | **class** | Class attribut of the component root element | `HTMLAttributes['class']` | No | `undefined` | - |
7
+ | **model-value** | `v-model` <br/>The current value of the input field in international format (e.g. +33612345678)<br/>**Example:** `"+33612345678"` | `string \| undefined \| null` | No | `undefined` | - |
8
+ | **country-code** | `v-model:country-code` <br/>The selected country code (e.g. "FR")<br/>**Example:** `"FR"` | `CountryCode \| undefined \| null` | No | `undefined` | - |
9
+ | **id** | Unique identifier for the component<br/>**Example:** `"phone-input-1"` | `string` | No | `undefined` | - |
10
+ | **placeholder** | Text displayed when the input is empty<br/>**Example:** `"Enter your phone number"` | `string` | No | `undefined` | - |
11
+ | **top-label** | Static label displayed above the input field. Unlike the floating label, this remains fixed<br/>**Example:** `"User Information"` | `string` | No | `undefined` | - |
12
+ | **label** | Label displayed above the input<br/>**Example:** `"Phone Number"` | `string` | No | `undefined` | - |
13
+ | **preferred-countries** | List of country codes to place first in the select list<br/>**Example:** `["FR", "BE", "GE"]` | `CountryCode[]` | No | `undefined` | - |
14
+ | **ignored-countries** | List of country codes to be removed from the select list<br/>**Example:** `["FR", "BE", "GE"]` | `CountryCode[]` | No | `undefined` | - |
15
+ | **only-countries** | List of country codes to only have the countries selected in the select list<br/>**Example:** `["FR", "BE", "GE"]` | `CountryCode[]` | No | `undefined` | - |
16
+ | **translations** | Locale strings of the component The default values are the translations of the MazUiTranslations plugin | `Partial<MazUiTranslationsNestedSchema['inputPhoneNumber']>` | No | `{ countrySelect: { error: 'Choose country', placeholder: 'Country code', searchPlaceholder: 'Search the country', }, phoneInput: { placeholder: 'Phone number', example: 'Example: {example}', }, }` | - |
17
+ | **list-position** | Position where the list of countries will be opened | `MazPopoverProps['position']` | No | `bottom left` | `top left, top right, bottom left, bottom right` |
18
+ | **color** | Component color applied | `MazColor` | No | `primary` | `primary, secondary, accent, info, success, warning, destructive, contrast` |
19
+ | **size** | Component size applied | `MazSize` | No | `md` | `xs, sm, md, lg, xl, mini` |
20
+ | **hide-flags** | Remove flags in country list | `boolean` | No | `false` | - |
21
+ | **flag-src** | Source of the flags, instead of the flagcdn.com CDN: a URL template (`/flags/{code}.svg`, `{CODE}` for uppercase) or a function giving the image source of a code. Use `loadCountryFlag` from `maz-ui/country-flags` for the flags of `@maz-ui/icons`. Can be set for the whole app with the `defaults.global.flagSrc` option of the MazUi plugin. | `MazCountryFlagSrc` | No | `undefined (flags from flagcdn.com)` | - |
22
+ | **disabled** | Make the input disabled | `boolean` | No | `false` | - |
23
+ | **required** | Make the input required | `boolean` | No | `false` | - |
24
+ | **example** | Show the phone number example | `boolean` | No | `true` | - |
25
+ | **search** | Disable search input in country list | `boolean` | No | `true` | - |
26
+ | **search-threshold** | Threshold of the search input in country list where 1 is a perfect match and 0 is a match with any character | `number` | No | `0.75` | - |
27
+ | **use-browser-locale** | If true, the browser locale will be used | `boolean` | No | `true` | - |
28
+ | **fetch-country** | The component will make a request (https://ipwho.is) to get the location of the user and use it to set the default country code | `boolean` | No | `false` | - |
29
+ | **hide-country-select** | Hide the country selector | `boolean` | No | `false` | - |
30
+ | **show-code-in-list** | Show country calling code in the country list | `boolean` | No | `false` | - |
31
+ | **custom-countries-list** | Replace country names | `Record<CountryCode, string>` | No | `undefined` | - |
32
+ | **auto-format** | Disabled auto-format when phone is valid | `"blur" \| "typing" \| "disabled" \| false` | No | `blur` | - |
33
+ | **country-locale** | Locale of country list<br/>**Example:** `"fr-FR"` | `string` | No | `undefined` | - |
34
+ | **validation-error** | Disable validation error UI | `boolean` | No | `true` | - |
35
+ | **validation-success** | Disable validation success UI | `boolean` | No | `true` | - |
36
+ | **success** | Add success UI | `boolean` | No | `false` | - |
37
+ | **error** | Add error UI | `boolean` | No | `false` | - |
38
+ | **warning** | Add warning UI | `boolean` | No | `false` | - |
39
+ | **display-country-name** | Will replace the calling code by the country name in the country selector | `boolean` | No | `false` | - |
40
+ | **block** | The input will be displayed in full width | `boolean` | No | `false` | - |
41
+ | **orientation** | Orientation of the inputs in the component | `'row' \| 'col' \| 'responsive'` | No | `responsive` | `row, col, responsive` |
42
+ | **country-select-attributes** | Meta attributes of the country input | `Record<string, unknown>` | No | `{ autocomplete: 'off', name: 'country' }` | - |
43
+ | **phone-input-attributes** | Meta attributes of the phone number input | `Record<string, unknown>` | No | `{ autocomplete: 'tel', name: 'phone', inputmode: 'tel' }` | - |
44
+ | **assistive-text** | Helper text displayed below the input to provide additional context or validation feedback<br/>**Example:** `"Must contain at least 8 characters"` | `string` | No | `undefined` | - |
45
+ | **hint** | Alternative text that replaces the label when provided. Useful for contextual hints<br/>**Example:** `"This phone number is not valid"` | `string` | No | `undefined` | - |
45
46
 
46
47
  ## Events
47
48
 
@@ -1,31 +1,32 @@
1
1
  ## Props
2
2
 
3
- | Name | Description | Type | Required | Default | Possible values |
4
- | ------------------------- | -------------------------------------------- | --------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------- | ------------------------------------ |
5
- | **style** | Style attribut of the component root element | `HTMLAttributes['style']` | No | `undefined` | - |
6
- | **class** | Class attribut of the component root element | `HTMLAttributes['class']` | No | `undefined` | - |
7
- | **id** | Id of the component | `string` | No | `undefined` | - |
8
- | **color** | Color of the component | `MazColor` | No | `primary` | - |
9
- | **size** | Size of the component | `MazSize` | No | `md` | - |
10
- | **preferred-codes** | Preferred countries to display | `Option['code'][]` | No | `undefined` | - |
11
- | **ignored-codes** | Ignored countries to display | `Option['code'][]` | No | `undefined` | - |
12
- | **only-codes** | Only countries to display | `Option['code'][]` | No | `undefined` | - |
13
- | **list-position** | Position of the list | `MazPopoverProps['position']` | No | `auto` | - |
14
- | **hide-flags** | Hide flags | `boolean` | No | `undefined` | - |
15
- | **search** | Display search input in options list | `boolean` | No | `true` | - |
16
- | **show-code-in-list** | Show code on list | `boolean` | No | `false` | - |
17
- | **locale** | Locale | `string` | No | `locale defined within the maz-ui plugin or browser locale or en-US` | - |
18
- | **success** | Success state | `boolean` | No | `undefined` | - |
19
- | **error** | Error state | `boolean` | No | `undefined` | - |
20
- | **warning** | Warning state | `boolean` | No | `undefined` | - |
21
- | **display-code** | | `boolean` | No | `undefined` | - |
22
- | **search-threshold** | Search threshold | `number` | No | `undefined` | - |
23
- | **translations** | Translations | `Partial<MazUiTranslationsNestedSchema['selectCountry']>` | No | `MazUiTranslationsNestedSchema['selectCountry']` | - |
24
- | **hint** | Hint message displayed | `string` | No | `undefined` | - |
25
- | **options** | Options | `Option[]` | No | `undefined` | - |
26
- | **display-names-options** | Display name type | `Intl.DisplayNamesOptions` | No | `{ type: 'region', languageDisplay: 'standard', fallback: 'code', style: 'long' }` | - |
27
- | **codes-type** | Codes type | `CodesType` | No | `defined by displayNamesOptions.type (if 'region', 'country' is used, otherwise 'iso')` | `iso' \| 'bcp' \| 'country' \| 'all` |
28
- | **open** | Open the select | `boolean` | No | `false` | - |
3
+ | Name | Description | Type | Required | Default | Possible values |
4
+ | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------- | ------------------------------------ |
5
+ | **style** | Style attribut of the component root element | `HTMLAttributes['style']` | No | `undefined` | - |
6
+ | **class** | Class attribut of the component root element | `HTMLAttributes['class']` | No | `undefined` | - |
7
+ | **id** | Id of the component | `string` | No | `undefined` | - |
8
+ | **color** | Color of the component | `MazColor` | No | `primary` | - |
9
+ | **size** | Size of the component | `MazSize` | No | `md` | - |
10
+ | **preferred-codes** | Preferred countries to display | `Option['code'][]` | No | `undefined` | - |
11
+ | **ignored-codes** | Ignored countries to display | `Option['code'][]` | No | `undefined` | - |
12
+ | **only-codes** | Only countries to display | `Option['code'][]` | No | `undefined` | - |
13
+ | **list-position** | Position of the list | `MazPopoverProps['position']` | No | `auto` | - |
14
+ | **hide-flags** | Hide flags | `boolean` | No | `undefined` | - |
15
+ | **flag-src** | Source of the flags, instead of the flagcdn.com CDN: - a URL template with the code, `{code}` (lowercase) or `{CODE}` (uppercase): `/flags/{code}.svg` - a function giving the image source of a code (URL or data URL), called when the flag becomes visible, or `undefined` to display the code in a badge Use `loadCountryFlag` from `maz-ui/country-flags` for the flags of `@maz-ui/icons`, without any request to a third party. Can be set for the whole app with the `defaults.global.flagSrc` option of the MazUi plugin. | `MazCountryFlagSrc` | No | `undefined (flags from flagcdn.com)` | - |
16
+ | **search** | Display search input in options list | `boolean` | No | `true` | - |
17
+ | **show-code-in-list** | Show code on list | `boolean` | No | `false` | - |
18
+ | **locale** | Locale | `string` | No | `locale defined within the maz-ui plugin or browser locale or en-US` | - |
19
+ | **success** | Success state | `boolean` | No | `undefined` | - |
20
+ | **error** | Error state | `boolean` | No | `undefined` | - |
21
+ | **warning** | Warning state | `boolean` | No | `undefined` | - |
22
+ | **display-code** | | `boolean` | No | `undefined` | - |
23
+ | **search-threshold** | Search threshold | `number` | No | `undefined` | - |
24
+ | **translations** | Translations | `Partial<MazUiTranslationsNestedSchema['selectCountry']>` | No | `MazUiTranslationsNestedSchema['selectCountry']` | - |
25
+ | **hint** | Hint message displayed | `string` | No | `undefined` | - |
26
+ | **options** | Options | `Option[]` | No | `undefined` | - |
27
+ | **display-names-options** | Display name type | `Intl.DisplayNamesOptions` | No | `{ type: 'region', languageDisplay: 'standard', fallback: 'code', style: 'long' }` | - |
28
+ | **codes-type** | Codes type | `CodesType` | No | `defined by displayNamesOptions.type (if 'region', 'country' is used, otherwise 'iso')` | `iso' \| 'bcp' \| 'country' \| 'all` |
29
+ | **open** | Open the select | `boolean` | No | `false` | - |
29
30
 
30
31
  ## Events
31
32
 
@@ -204,6 +204,11 @@ Customize what information is shown to users.
204
204
  assistive-text="Text-only country selection"
205
205
  hide-flags
206
206
  />
207
+ <MazInputPhoneNumber
208
+ top-label="Flags of maz-ui"
209
+ assistive-text="No request to flagcdn.com, works offline"
210
+ :flag-src="loadCountryFlag"
211
+ />
207
212
  </div>
208
213
 
209
214
  <template #code>
@@ -224,12 +229,36 @@ Customize what information is shown to users.
224
229
 
225
230
  <!-- Hide country flags -->
226
231
  <MazInputPhoneNumber hide-flags />
232
+
233
+ <!-- Flags of maz-ui, no request to flagcdn.com: import { loadCountryFlag } from 'maz-ui/country-flags' -->
234
+ <MazInputPhoneNumber :flag-src="loadCountryFlag" />
235
+
236
+ <!-- Your own files: public/flags/fr.svg... -->
237
+ <MazInputPhoneNumber flag-src="/flags/{code}.svg" />
227
238
  </template>
228
239
  ```
229
240
 
230
241
  </template>
231
242
  </ComponentDemo>
232
243
 
244
+ ### Flags source
245
+
246
+ By default, the flags come from the [flagcdn.com](https://flagcdn.com) CDN. The `flag-src` prop, passed to the country selector, takes:
247
+
248
+ - `loadCountryFlag` from `maz-ui/country-flags`: the flags of `@maz-ui/icons`, without any request to a third party, offline (hybrid apps with Capacitor or Cordova, PWAs);
249
+ - a URL template of your own files: `'/flags/{code}.svg'` (`{CODE}` for uppercase codes);
250
+ - your own function: `(code) => string | undefined | Promise<string | undefined>`.
251
+
252
+ Each flag is loaded only when visible, and a code without flag displays a badge. Set it once for the whole app with `defaults.global.flagSrc` of the MazUi plugin, or `mazUi.flags` of the Nuxt module (`'local'` or a URL template):
253
+
254
+ ```ts
255
+ import { loadCountryFlag } from 'maz-ui/country-flags'
256
+
257
+ app.use(MazUi, { theme: { preset: mazUi }, defaults: { global: { flagSrc: loadCountryFlag } } })
258
+ ```
259
+
260
+ See [MazSelectCountry](./maz-select-country.md#flags-source) for the details (bundle, Content Security Policy, PWA precache).
261
+
233
262
  ## Smart Country Detection
234
263
 
235
264
  Let the component automatically detect the user's country.
@@ -886,6 +915,7 @@ interface MazInputPhoneNumberData {
886
915
  <!--@include: ./../../.vitepress/generated-docs/maz-input-phone-number.doc.md-->
887
916
 
888
917
  <script setup lang="ts">
918
+ import { loadCountryFlag } from 'maz-ui/country-flags'
889
919
  import { ref } from 'vue'
890
920
 
891
921
  // Basic usage
@@ -291,6 +291,141 @@ Configure how country/language names are displayed using the `displayNamesOption
291
291
  </template>
292
292
  </ComponentDemo>
293
293
 
294
+ ## Flags source
295
+
296
+ By default, the flags are images of the [flagcdn.com](https://flagcdn.com) CDN: each user's browser requests them from this third party. The `flag-src` prop changes where they come from, in four ways:
297
+
298
+ | Source | `flag-src` | Network |
299
+ | --- | --- | --- |
300
+ | CDN (default) | not set | flagcdn.com |
301
+ | Flags of maz-ui | `loadCountryFlag` from `maz-ui/country-flags` | none (works offline) |
302
+ | Your own files | URL template: `'/flags/{code}.svg'` | your server |
303
+ | Your own function | `(code) => string \| undefined \| Promise<string \| undefined>` | yours |
304
+
305
+ In every case, a flag is only loaded when it becomes visible (the selected country, then the rows of the open list in view), and a code without flag displays the colored badge.
306
+
307
+ ### For the whole app
308
+
309
+ Set it once instead of on every component: the `flag-src` of `MazSelectCountry` and `MazInputPhoneNumber` both default to `defaults.global.flagSrc` (see [Global component defaults](../guide/global-defaults.md)). A `flag-src` set on a component always wins.
310
+
311
+ ```ts
312
+ // Vue: main.ts
313
+ import { loadCountryFlag } from 'maz-ui/country-flags'
314
+ import { MazUi } from 'maz-ui/plugins/maz-ui'
315
+
316
+ app.use(MazUi, {
317
+ theme: { preset: mazUi },
318
+ defaults: {
319
+ global: { flagSrc: loadCountryFlag }, // or a URL template: '/flags/{code}.svg'
320
+ },
321
+ })
322
+ ```
323
+
324
+ ```ts
325
+ // Nuxt: nuxt.config.ts
326
+ export default defineNuxtConfig({
327
+ modules: ['@maz-ui/nuxt'],
328
+ mazUi: {
329
+ flags: 'local', // 'cdn' (default) | 'local' | a URL template: '/flags/{code}.svg'
330
+ },
331
+ })
332
+ ```
333
+
334
+ ### Flags of maz-ui, offline
335
+
336
+ `loadCountryFlag` gives the square flag of a code from the 256 flags of `@maz-ui/icons`, as a `data:image/svg+xml` URL: no request to a third party (nothing to allow for flagcdn.com in your Content Security Policy, the user's IP is not sent to it), and the component works offline (hybrid apps with Capacitor or Cordova, PWAs, intranets).
337
+
338
+ <ComponentDemo>
339
+ <div class="maz:flex maz:gap-4 maz:flex-wrap">
340
+ <MazSelectCountry
341
+ v-model="localFlagsExample"
342
+ label="Country (flags of maz-ui)"
343
+ :flag-src="loadCountryFlag"
344
+ />
345
+ </div>
346
+
347
+ <template #code>
348
+
349
+ ```vue
350
+ <script lang="ts" setup>
351
+ import { loadCountryFlag } from 'maz-ui/country-flags'
352
+ import { ref } from 'vue'
353
+
354
+ const selectedCountry = ref('FR')
355
+ </script>
356
+
357
+ <template>
358
+ <MazSelectCountry
359
+ v-model="selectedCountry"
360
+ label="Country (flags of maz-ui)"
361
+ :flag-src="loadCountryFlag"
362
+ />
363
+ </template>
364
+ ```
365
+
366
+ </template>
367
+ </ComponentDemo>
368
+
369
+ How it stays light:
370
+
371
+ - Nothing in maz-ui imports `maz-ui/country-flags`: an app that does not import it has **no flag file at all** in its build.
372
+ - Once imported, your bundler emits **one small chunk per flag** (256 files, from a few hundred bytes to a few kilobytes each). None is preloaded: only the flags displayed are downloaded.
373
+ - The loader itself (a table of 256 dynamic imports, about 4 kB gzipped) goes into the chunk that imports it. To keep it out of your entry chunk, import it on demand (the Nuxt option `flags: 'local'` does it for you):
374
+
375
+ ```ts
376
+ const flagSrc = (code: string) => import('maz-ui/country-flags').then(({ loadCountryFlag }) => loadCountryFlag(code))
377
+ ```
378
+
379
+ ::: tip Content Security Policy
380
+ The flags are `data:` URLs: a strict CSP must allow `img-src data:` (already needed by the lazy images of maz-ui).
381
+ :::
382
+
383
+ ::: tip PWA precache
384
+ Once you use `loadCountryFlag`, the 256 flag chunks are part of your build, so a service worker that precaches every `**/*.js` downloads all of them at install. Keep them (every flag available offline) or exclude them and let them load on demand. With Vite, the chunks are named after their module, `MazFlagSquareFR-[hash].js`:
385
+
386
+ ```ts
387
+ // vite-plugin-pwa
388
+ VitePWA({ workbox: { globIgnores: ['**/MazFlagSquare*.js'] } })
389
+ ```
390
+
391
+ Nuxt names its chunks `_nuxt/[hash].js` only: name the flag chunks yourself to exclude them, e.g. `vite.build.rollupOptions.output.chunkFileNames: chunk => chunk.name.startsWith('MazFlagSquare') ? '_nuxt/flags/[name].[hash].js' : '_nuxt/[hash].js'`, then ignore `**/_nuxt/flags/**`.
392
+ :::
393
+
394
+ ### Your own files
395
+
396
+ A URL template, with `{code}` for the lowercase code and `{CODE}` for the uppercase code. The images are lazy loaded like the CDN ones. A missing image displays the badge.
397
+
398
+ ```vue
399
+ <template>
400
+ <!-- public/flags/fr.svg, public/flags/de.svg... -->
401
+ <MazSelectCountry v-model="selectedCountry" flag-src="/flags/{code}.svg" />
402
+
403
+ <!-- another host, uppercase codes -->
404
+ <MazSelectCountry v-model="selectedCountry" flag-src="https://assets.example.com/flags/{CODE}.png" />
405
+ </template>
406
+ ```
407
+
408
+ ### Your own function
409
+
410
+ A function receives the country code of each flag when it becomes visible, and returns the image source (URL or data URL), or `undefined` to display the badge. It can be async: only the flags displayed are loaded.
411
+
412
+ ```vue
413
+ <script lang="ts" setup>
414
+ // One file per flag in your project, loaded on demand (Vite turns this import into one chunk per file)
415
+ function flagSrc(code: string) {
416
+ return import(`./assets/flags/${code.toLowerCase()}.svg?url`)
417
+ .then(module => module.default)
418
+ .catch(() => undefined)
419
+ }
420
+ </script>
421
+
422
+ <template>
423
+ <MazSelectCountry v-model="selectedCountry" :flag-src="flagSrc" />
424
+ </template>
425
+ ```
426
+
427
+ You can also replace the flags entirely with the `selector-flag` and `country-list-flag` slots.
428
+
294
429
  ## Without flags
295
430
 
296
431
  Hide country flags using the `hideFlags` prop for a cleaner text-only interface.
@@ -564,7 +699,7 @@ The `MazSelectCountry` component is built on top of `MazSelect` and leverages th
564
699
 
565
700
  - **Automatic localization**: Country and language names are displayed in the user's locale
566
701
  - **Built-in search**: Users can quickly find countries by typing
567
- - **Flag integration**: Automatic flag display using country codes
702
+ - **Flag integration**: Automatic flag display using country codes, from the flagcdn.com CDN, the flags of maz-ui (offline) or your own files
568
703
  - **Flexible filtering**: Support for preferred, ignored, or specific country lists
569
704
  - **Custom options**: Override default behavior with custom data
570
705
  - **Accessibility**: Full keyboard navigation and screen reader support
@@ -592,6 +727,7 @@ const allCountries = getAllDisplayNames({
592
727
  This ensures consistent internationalization across your application while providing maximum flexibility for different use cases.
593
728
 
594
729
  <script setup>
730
+ import { loadCountryFlag } from 'maz-ui/country-flags'
595
731
  import { ref } from 'vue'
596
732
 
597
733
  // Basic examples
@@ -613,6 +749,7 @@ const excludeExample = ref()
613
749
  const shortExample = ref()
614
750
  const languageNarrowExample = ref()
615
751
  const noFlagsExample = ref()
752
+ const localFlagsExample = ref('FR')
616
753
  const frenchExample = ref()
617
754
  const spanishExample = ref()
618
755
  const successExample = ref()
@@ -159,6 +159,9 @@ export default defineNuxtConfig({
159
159
  MazCard: { bordered: false, elevation: true },
160
160
  },
161
161
 
162
+ // Country flags of MazSelectCountry and MazInputPhoneNumber: 'cdn' (default), 'local' (offline) or '/flags/{code}.svg'
163
+ flags: 'local',
164
+
162
165
  // Plugins (not enabled by default)
163
166
  plugins: {
164
167
  aos: true,
@@ -289,6 +292,23 @@ const defaults = {
289
292
 
290
293
  See the [Global component defaults guide](/guide/global-defaults) for the full list of globalizable props.
291
294
 
295
+ ### Country Flags
296
+
297
+ Source of the flags of `MazSelectCountry` and `MazInputPhoneNumber`. A `flag-src` set on a component wins.
298
+
299
+ ```ts
300
+ export default defineNuxtConfig({
301
+ mazUi: {
302
+ // 'cdn' (default): flagcdn.com
303
+ // 'local': flags of @maz-ui/icons, one chunk per flag loaded when visible, no request to a third party
304
+ // '/flags/{code}.svg': your own files ({CODE} for uppercase codes)
305
+ flags: 'local',
306
+ },
307
+ })
308
+ ```
309
+
310
+ Nothing is added to your build unless `flags` is `'local'`. See [MazSelectCountry](/components/maz-select-country#flags-source) for the details (Content Security Policy, PWA precache).
311
+
292
312
  ## Theme Strategies Explained
293
313
 
294
314
  ### Runtime (Recommended)
@@ -63,7 +63,7 @@ export default defineNuxtConfig({
63
63
 
64
64
  ## `global` vs per-component
65
65
 
66
- - `defaults.global` holds **cross-cutting** props shared by many components: `roundedSize` and `size`. Set them once and every component that exposes them picks the value up.
66
+ - `defaults.global` holds **cross-cutting** props shared by many components: `roundedSize`, `size` and `flagSrc`. Set them once and every component that exposes them picks the value up.
67
67
  - `defaults.<ComponentName>` holds **per-component** props (including booleans such as `bordered`, `elevation`, `padding`). A per-component entry always wins over `global`.
68
68
 
69
69
  ```ts
@@ -88,6 +88,7 @@ defaults: {
88
88
  | Prop | Type | Components |
89
89
  | --- | --- | --- |
90
90
  | `roundedSize` | `MazRoundedSize` (`'none' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'`) | `MazBtn`, `MazBtnGroup`, `MazContainer`, `MazInput`, `MazTextarea`, `MazTable`, `MazBadge`, `MazAlert`, `MazAvatar`, `MazSkeleton`, `MazTimeline` |
91
+ | `flagSrc` | `MazCountryFlagSrc` (URL template or function, e.g. `loadCountryFlag` from `maz-ui/country-flags`) | `MazSelectCountry`, `MazInputPhoneNumber` (see [flags source](../components/maz-select-country.md#flags-source)) |
91
92
  | `size` | `MazSize` (`'mini' \| 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl'`) | `MazBtn`, `MazBtnGroup`, `MazBadge`, `MazInput`, `MazSelect`, `MazSelectCountry`, `MazInputNumber`, `MazInputTags`, `MazInputPhoneNumber`, `MazCheckbox`, `MazRadio`, `MazRadioButtons`, `MazDropdown`, `MazPagination`, `MazTable`, `MazTimeline` |
92
93
  | `bordered`, `elevation`, `padding`, `transparent`, `overflowHidden` | `boolean` | `MazContainer` |
93
94
  | `bordered`, `elevation`, `padding`, `radius`, `scale`, `overflowHidden` | `boolean` | `MazCard` |
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@maz-ui/mcp",
3
3
  "type": "module",
4
- "version": "5.0.0-beta.50",
4
+ "version": "5.0.0-beta.51",
5
5
  "description": "Maz-UI ModelContextProtocol Client",
6
6
  "author": "Louis Mazel <me@loicmazuel.com>",
7
7
  "license": "MIT",
@@ -43,7 +43,7 @@
43
43
  "dependencies": {
44
44
  "@maz-ui/utils": "5.0.0-beta.46",
45
45
  "@modelcontextprotocol/sdk": "^1.32.0",
46
- "maz-ui": "5.0.0-beta.50"
46
+ "maz-ui": "5.0.0-beta.51"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@maz-ui/eslint-config": "5.0.0-beta.47",