@alikhalilll/ui 1.1.1 → 1.2.0

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.
@@ -49,6 +49,8 @@ emptyText: string;
49
49
  loadingText: string;
50
50
  suggestedLabel: string;
51
51
  allCountriesLabel: string;
52
+ countryLabel: string;
53
+ selectCountryLabel: string;
52
54
  suggestedLimit: number;
53
55
  maxResults: number;
54
56
  kbdOpen: string | null;
@@ -96,6 +98,12 @@ declare type __VLS_Props_2 = {
96
98
  /** Override the right-side kbd hints. Pass `null` to hide. */
97
99
  kbdOpen?: string | null;
98
100
  kbdClose?: string | null;
101
+ /** BCP-47 locale — country names render localized via `Intl.DisplayNames`. */
102
+ locale?: string;
103
+ /** Prefix of the trigger's `aria-label` when a country is selected, e.g. `"Country"`. */
104
+ countryLabel?: string;
105
+ /** Trigger's `aria-label` when no country is selected. */
106
+ selectCountryLabel?: string;
99
107
  };
100
108
 
101
109
  declare type __VLS_Props_3 = {
@@ -391,12 +399,32 @@ export declare const ACountrySelect: __VLS_WithTemplateSlots_2<typeof __VLS_comp
391
399
 
392
400
  export declare const ATellInput: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
393
401
 
402
+ /** Text direction for the field. `'auto'` (or omitting the prop) inherits from the
403
+ * nearest `[dir]` ancestor / `<html dir>`; `'ltr'` / `'rtl'` force it. */
404
+ export declare type ATellInputDir = 'ltr' | 'rtl' | 'auto';
405
+
394
406
  export declare interface ATellInputProps {
395
407
  class?: HTMLAttributes['class'];
396
408
  placeholder?: string;
397
409
  disabled?: boolean;
398
410
  loading?: boolean;
399
411
  size?: ATellInputSize;
412
+ /**
413
+ * Text direction. Omit (or pass `'auto'`) to inherit from the page — RTL pages get an
414
+ * RTL field automatically. Pass `'ltr'` / `'rtl'` to force it.
415
+ */
416
+ dir?: ATellInputDir;
417
+ /**
418
+ * BCP-47 locale (e.g. `'ar'`, `'fr'`). When set, country names render localized via
419
+ * `Intl.DisplayNames` and the format hint uses the locale's numerals.
420
+ */
421
+ locale?: string;
422
+ /**
423
+ * Localized UI strings. A single bag covering the picker, validation errors, and a11y
424
+ * labels. Individual props (`searchPlaceholder`, `emptyText`, `loadingText`,
425
+ * `errorMessages`) take precedence over the matching `messages` key when both are set.
426
+ */
427
+ messages?: TellInputMessagesInput;
400
428
  /**
401
429
  * Whitelist of allowed dial-digit codes (no `+`), e.g. `['20', '966']`.
402
430
  * Countries outside this list are still shown in the picker but rendered as disabled.
@@ -467,6 +495,9 @@ export declare interface CountryOption<T = RestCountry> {
467
495
 
468
496
  export declare const DEFAULT_ERROR_MESSAGES: Record<PhoneValidationReason, string>;
469
497
 
498
+ /** English defaults for every {@link TellInputMessages} key. */
499
+ export declare const DEFAULT_MESSAGES: TellInputMessages;
500
+
470
501
  /**
471
502
  * Default flag URL builder — flagcdn.com hosts PNG flags at multiple widths and is
472
503
  * generous with caching + no API key required. Swap via the `flagUrl` prop on
@@ -528,6 +559,30 @@ declare interface ExtendedProps extends ATellInputProps {
528
559
 
529
560
  export declare type FlagUrlBuilder = (iso2: string, width: number) => string;
530
561
 
562
+ /**
563
+ * Base code points of contiguous decimal-digit blocks. Each block runs `base`‥`base+9`
564
+ * for digit `0`‥`9`, so the ASCII digit is `codePoint - base`. Add a script by appending
565
+ * one entry here.
566
+ */
567
+ export declare const LOCALE_DIGIT_RANGES: {
568
+ name: string;
569
+ base: number;
570
+ }[];
571
+
572
+ /**
573
+ * Return a copy of the country list with display names localized to `locale` via
574
+ * `Intl.DisplayNames`. `search_key` is rebuilt (keeping the English name too) so search
575
+ * still matches either spelling. Unknown locales / regions fall back to the English name.
576
+ */
577
+ export declare function localizeCountries(list: CountryOption[], locale?: string): CountryOption[];
578
+
579
+ /**
580
+ * Replace any supported non-ASCII decimal digit with its ASCII equivalent. Every other
581
+ * character (spaces, `+`, separators, letters) is left untouched — callers still run their
582
+ * own `\D` cleanup afterwards.
583
+ */
584
+ export declare function normalizeDigits(input: string): string;
585
+
531
586
  export declare interface PhoneRequiredInfo {
532
587
  iso2: string;
533
588
  dial_code: string;
@@ -560,6 +615,12 @@ export declare interface PhoneValidationResult {
560
615
  details?: Record<string, unknown>;
561
616
  }
562
617
 
618
+ /**
619
+ * Merge a partial `messages` override onto the English defaults. Used internally by
620
+ * `ATellInput` to resolve a complete {@link TellInputMessages} object.
621
+ */
622
+ export declare function resolveMessages(input?: TellInputMessagesInput): TellInputMessages;
623
+
563
624
  export declare interface RestCountry {
564
625
  name?: {
565
626
  common?: string;
@@ -587,6 +648,36 @@ declare function selectCountry(option: CountryOption): void;
587
648
  */
588
649
  declare type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
589
650
 
651
+ /**
652
+ * Every user-facing string in the tell-input UI, bundled so a consumer can localize the
653
+ * component in one prop. Each key has an English default in {@link DEFAULT_MESSAGES}.
654
+ */
655
+ export declare interface TellInputMessages {
656
+ /** Placeholder of the country-picker search box. */
657
+ searchPlaceholder: string;
658
+ /** Shown when a search yields no countries. */
659
+ emptyText: string;
660
+ /** Shown while the country list is loading. */
661
+ loadingText: string;
662
+ /** Header of the "Suggested" group (current + recent picks). */
663
+ suggestedLabel: string;
664
+ /** Header of the full country list. */
665
+ allCountriesLabel: string;
666
+ /** Validation error text, keyed by reason. */
667
+ errorMessages: Record<PhoneValidationReason, string>;
668
+ /** Prefix of the country trigger's `aria-label`, e.g. `"Country: Egypt"`. */
669
+ countryLabel: string;
670
+ /** `aria-label` of the country trigger when no country is selected. */
671
+ selectCountryLabel: string;
672
+ /** `aria-label` of the phone input element. */
673
+ phoneInputLabel: string;
674
+ }
675
+
676
+ /** Partial override shape for the `messages` prop — every key (and every error reason) is optional. */
677
+ export declare type TellInputMessagesInput = Partial<Omit<TellInputMessages, 'errorMessages'>> & {
678
+ errorMessages?: Partial<Record<PhoneValidationReason, string>>;
679
+ };
680
+
590
681
  /**
591
682
  * Reactive wrapper. Kicks off detection in `onMounted` so SSR renders an empty value and the
592
683
  * client patches in the real country once resolved.
@@ -616,7 +707,7 @@ export declare interface UsePhoneValidationReturn {
616
707
  getRequiredInfo(country: {
617
708
  iso2: string;
618
709
  dial_code?: string;
619
- }): PhoneRequiredInfo | null;
710
+ }, locale?: string): PhoneRequiredInfo | null;
620
711
  validate(input: ValidateArgs): PhoneValidationResult;
621
712
  }
622
713
 
@@ -626,12 +717,16 @@ export declare type ValidateArgs = {
626
717
  dial_code?: string;
627
718
  } | null | undefined;
628
719
  phone?: undefined;
720
+ /** BCP-47 locale — localizes the numerals in the returned `required.format_hint`. */
721
+ locale?: string;
629
722
  } | {
630
723
  country: {
631
724
  iso2: string;
632
725
  dial_code?: string;
633
726
  } | null | undefined;
634
727
  phone: string | null;
728
+ /** BCP-47 locale — localizes the numerals in the returned `required.format_hint`. */
729
+ locale?: string;
635
730
  };
636
731
 
637
732
  export { }
@@ -1,13 +1,18 @@
1
- import { _ as e, a as s, b as l, D as n, c as u, d as o, e as r, u as A, f as c } from "./chunks/ATellInput.vue_vue_type_script_setup_true_lang-Clc-B8SW.mjs";
1
+ import { _ as e, a as t, b as l, D as n, c as o, L as r, d as u, e as i, f as A, l as E, n as S, r as C, u as D, g as _ } from "./chunks/ATellInput.vue_vue_type_script_setup_true_lang-Bv_lLV_l.mjs";
2
2
  export {
3
3
  e as ACountryFlag,
4
- s as ACountrySelect,
4
+ t as ACountrySelect,
5
5
  l as ATellInput,
6
6
  n as DEFAULT_ERROR_MESSAGES,
7
+ o as DEFAULT_MESSAGES,
8
+ r as LOCALE_DIGIT_RANGES,
7
9
  u as aTellInputVariants,
8
- o as defaultFlagUrl,
9
- r as detectCountry,
10
- A as useCountryDetection,
11
- c as usePhoneValidation
10
+ i as defaultFlagUrl,
11
+ A as detectCountry,
12
+ E as localizeCountries,
13
+ S as normalizeDigits,
14
+ C as resolveMessages,
15
+ D as useCountryDetection,
16
+ _ as usePhoneValidation
12
17
  };
13
18
  //# sourceMappingURL=tell-input.mjs.map
@@ -1,6 +1,6 @@
1
1
  # `@alikhalilll/ui/tell-input`
2
2
 
3
- Vue 3 phone-number input with smart country detection (libphonenumber-js + IP/timezone/locale hint), a responsive popover/drawer country picker, and a structured `PhoneValidationResult` exposed via template ref.
3
+ Vue 3 phone-number input with smart country detection (libphonenumber-js + IP/timezone/locale hint), a responsive popover/drawer country picker, and a structured `PhoneValidationResult` exposed via template ref. RTL-aware, localisable, and accepts alternative numeral systems.
4
4
 
5
5
  ## Install
6
6
 
@@ -31,7 +31,22 @@ const country = ref<number | null>(null);
31
31
  </template>
32
32
  ```
33
33
 
34
- The default shape is a plain phone input with the country picker hidden. As the user types or pastes, detection runs (debounced) against known dial codes; on first match the picker slides in pre-filled and `phone` is normalised to the national significant number — `01066105963` becomes `1066105963`, `+447911123456` becomes `7911123456`.
34
+ The default shape is a plain phone input with the country picker hidden. As the user types or pastes, detection runs (debounced) against known dial codes; on first match a flag-only trigger reveals at the **end** of the field, the dial code shows as a static prefix inside the input, and `phone` is normalised to the national significant number — `01066105963` becomes `1066105963`, `+447911123456` becomes `7911123456`.
35
+
36
+ ## Internationalization
37
+
38
+ - **RTL** — direction inherits from the page (`<div dir="rtl">` / `<html dir="rtl">`), or force it with `dir="ltr"` / `dir="rtl"`. The phone field row stays LTR (dial prefix → digits → flag); only the helper/error text and the country popover follow the page direction.
39
+ - **`locale`** — localises country names (`Intl.DisplayNames`) and the format-hint numerals.
40
+ - **`messages`** — one bag for every UI string (picker labels, validation errors, a11y labels).
41
+ - **Alternative numerals** — digits typed as Arabic-Indic (`٠-٩`), Persian (`۰-۹`), Devanagari, or Bengali are normalised to ASCII. `normalizeDigits` is exported for standalone use.
42
+
43
+ ```vue
44
+ <template>
45
+ <div dir="rtl">
46
+ <ATellInput v-model:phone="phone" v-model:country="country" locale="ar" :messages="ar" />
47
+ </div>
48
+ </template>
49
+ ```
35
50
 
36
51
  ## Variants
37
52
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alikhalilll/ui",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "Headless, shadcn-vue style Vue 3 component library — every component is its own importable subpath (`@alikhalilll/ui/tell-input`, `@alikhalilll/ui/popover`, …) so users pay only for what they actually use.",
5
5
  "license": "MIT",
6
6
  "author": "alikhalilll",