phonefield 0.1.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.
- package/README.md +84 -0
- package/dist/chunk-ERF62DTM.js +1 -0
- package/dist/index.d.ts +81 -0
- package/dist/index.js +1 -0
- package/dist/types-BPc8XSky.d.ts +32 -0
- package/dist/utils.d.ts +68 -0
- package/dist/utils.js +1 -0
- package/package.json +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
## PhoneField
|
|
2
|
+
|
|
3
|
+
Composable phone field primitive built with Base UI and libphonenumber-js.
|
|
4
|
+
|
|
5
|
+
- Country picker with localized names, dial codes, and flags.
|
|
6
|
+
- As-you-type formatting via `formatOnType`.
|
|
7
|
+
- Controlled and uncontrolled usage.
|
|
8
|
+
- FormData integration via `name` on `PhoneField.Root`.
|
|
9
|
+
- Shared utils for parsing, validation, and country metadata.
|
|
10
|
+
|
|
11
|
+
### Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pnpm add phonefield
|
|
15
|
+
# or
|
|
16
|
+
npm install phonefield
|
|
17
|
+
yarn add phonefield
|
|
18
|
+
bun add phonefield
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Usage
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { PhoneField } from "phonefield";
|
|
25
|
+
|
|
26
|
+
export function SignupPhone() {
|
|
27
|
+
return (
|
|
28
|
+
<PhoneField.Root defaultCountry="US" lang="en">
|
|
29
|
+
<PhoneField.Country />
|
|
30
|
+
<PhoneField.Input />
|
|
31
|
+
</PhoneField.Root>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
import * as React from "react";
|
|
38
|
+
import { PhoneField } from "phonefield";
|
|
39
|
+
|
|
40
|
+
export function ControlledExample() {
|
|
41
|
+
const [phone, setPhone] = React.useState<PhoneField.Value>({
|
|
42
|
+
countryIso2: "US",
|
|
43
|
+
countryDialCode: "1",
|
|
44
|
+
nationalNumber: "",
|
|
45
|
+
e164: null,
|
|
46
|
+
isValid: false,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<PhoneField.Root value={phone} onValueChange={setPhone}>
|
|
51
|
+
<PhoneField.Country />
|
|
52
|
+
<PhoneField.Input />
|
|
53
|
+
</PhoneField.Root>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### FormData
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
import { PhoneField } from "phonefield";
|
|
62
|
+
import { PhoneFieldUtils } from "phonefield/utils";
|
|
63
|
+
|
|
64
|
+
function ExampleForm() {
|
|
65
|
+
return (
|
|
66
|
+
<form
|
|
67
|
+
onSubmit={(event) => {
|
|
68
|
+
event.preventDefault();
|
|
69
|
+
const formData = new FormData(event.currentTarget);
|
|
70
|
+
const phone = PhoneFieldUtils.fromFormData(formData, "phone");
|
|
71
|
+
// phone -> PhoneField.Value | null
|
|
72
|
+
}}
|
|
73
|
+
>
|
|
74
|
+
<PhoneField.Root name="phone" defaultCountry="US">
|
|
75
|
+
<PhoneField.Country />
|
|
76
|
+
<PhoneField.Input />
|
|
77
|
+
</PhoneField.Root>
|
|
78
|
+
</form>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
More documentation and API reference: https://phonefield.vercel.app
|
|
84
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{getCountries as n,AsYouType as t,parsePhoneNumberFromString as e,getCountryCallingCode as r}from"libphonenumber-js/min";function o(n){if("undefined"==typeof Intl||void 0===Intl.DisplayNames)return null;try{return new Intl.DisplayNames([n],{type:"region"})}catch{return null}}var i=o("en"),u=n();function a(n,t){return t?.of(n)??i?.of(n)??n}function l(n){return n.toUpperCase().replace(/./g,n=>String.fromCodePoint(n.charCodeAt(0)+127397))}function c(n){if(!n)return"en";try{return Intl.getCanonicalLocales(n)[0]??"en"}catch{return Array.isArray(n)?n[0]??"en":n}}var s=new Map;function f(n){const t=c(n),e=s.get(t);if(e)return e;const i=function(n){const t=o(n),e=function(n){if("undefined"==typeof Intl||void 0===Intl.Collator)return null;try{return new Intl.Collator(n)}catch{return null}}(n),i=u.map(n=>({iso2:n,name:a(n,t),dialCode:`+${r(n)}`,flag:l(n)})).sort((t,r)=>e?e.compare(t.name,r.name):t.name.localeCompare(r.name,n));return new Map(i.map(n=>[n.iso2,n]))}(t);return s.set(t,i),i}var d="US";function p(){return f("en")}function y(n){return n.replace(/\D+/g,"")}function m(n,t){if(!t?.length){const t=Array.from(n.values());if(0===t.length)throw new Error("PhoneField.Root requires at least one valid country code.");return t}const e=t,r=new Set,o=[];for(const t of e){if(r.has(t))continue;r.add(t);const e=n.get(t);e&&o.push(e)}if(0===o.length)throw new Error("PhoneField.Root requires at least one valid country code.");return o}function g(n,t){if(0===n.length)throw new Error("PhoneField.Root requires at least one available country.");let e=n[0];for(const r of n)if("US"===r.iso2&&(e=r),t&&r.iso2===t)return r;return e}function h(n,r,o){const i=y(r),u=o?i?new t(n.iso2).input(i):"":r,a=function(n){return y(n.dialCode)}(n),l=i?`+${a}${i}`:null,c=l?e(l):void 0;return{countryIso2:n.iso2,countryDialCode:a,nationalNumber:u,e164:l,isValid:c?.isValid()??!1}}function C(n){return`${n.name} ${n.iso2} ${n.dialCode}`}function v(n,t){if("string"==typeof n)return e(n,t?.defaultCountry);const r=n.e164?e(n.e164):void 0;if(r)return r;const o=`+${n.countryDialCode}${y(n.nationalNumber)}`;return e(o,n.countryIso2)}function w(n,t){return v(n,t)?.isValid()??!1}function I(n){return!(!n||"object"!=typeof n||"string"!=typeof n.countryIso2||"string"!=typeof n.countryDialCode||"string"!=typeof n.nationalNumber||"string"!=typeof n.e164&&null!==n.e164||"boolean"!=typeof n.isValid)}function b(n,t){const e=n.get(t);if("string"!=typeof e)return null;try{const n=JSON.parse(e);return I(n)?n:null}catch{return null}}var $={parse:v,isValid:w,fromFormData:b,getCountries:f,get countries(){return p()}};export{d as DEFAULT_COUNTRY,$ as PhoneFieldUtils,h as buildValue,C as defaultCountrySearchText,b as fromFormData,f as getCountriesMap,p as getDefaultCountriesMap,I as isPhoneFieldValue,w as isValidPhoneField,c as normalizeLang,y as onlyDigits,v as parsePhoneField,g as resolveCountry,m as toAvailableCountries};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { Combobox } from '@base-ui/react/combobox';
|
|
3
|
+
import { Input } from '@base-ui/react/input';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { P as PhoneFieldCountry, a as PhoneFieldCountryMap, b as PhoneFieldCountryCodeValue, c as PhoneFieldCountryName, d as PhoneFieldLang, e as PhoneFieldValue } from './types-BPc8XSky.js';
|
|
6
|
+
import 'libphonenumber-js/min';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Root container for the phone field. Provides context to Country and Input.
|
|
10
|
+
* Supports controlled and uncontrolled usage, optional FormData serialization via `name`, and country subset.
|
|
11
|
+
*/
|
|
12
|
+
declare function Root({ value, defaultValue, onValueChange, defaultCountry, countries, lang, name, formatOnType, children, className, ...props }: PhoneField.RootProps): react_jsx_runtime.JSX.Element;
|
|
13
|
+
/**
|
|
14
|
+
* Country combobox: trigger + searchable list. Use `slots` to style trigger, popup, list, item, etc.
|
|
15
|
+
*/
|
|
16
|
+
declare function Country({ placeholder, noResultsText, inputPlaceholder, icon, slots, renderCountryItem, renderCountryValue, }: PhoneField.CountryProps): react_jsx_runtime.JSX.Element;
|
|
17
|
+
declare const PhoneField: {
|
|
18
|
+
Root: typeof Root;
|
|
19
|
+
Country: typeof Country;
|
|
20
|
+
Input: ({ className, onValueChange, type, onKeyDown, ref, ...props }: PhoneField.InputProps) => react_jsx_runtime.JSX.Element;
|
|
21
|
+
};
|
|
22
|
+
declare namespace PhoneField {
|
|
23
|
+
/** Country descriptor: iso2, name, dialCode, flag. */
|
|
24
|
+
type Country = PhoneFieldCountry;
|
|
25
|
+
/** Read-only map of ISO2 to country. */
|
|
26
|
+
type CountryMap = PhoneFieldCountryMap;
|
|
27
|
+
/** ISO2 country code (e.g. "US", "GB"). */
|
|
28
|
+
type CountryCodeValue = PhoneFieldCountryCodeValue;
|
|
29
|
+
/** Alias for ISO2 country code. */
|
|
30
|
+
type CountryName = PhoneFieldCountryName;
|
|
31
|
+
/** BCP 47 locale for country names and sorting. */
|
|
32
|
+
type Lang = PhoneFieldLang;
|
|
33
|
+
/** Emitted/controlled value: countryIso2, countryDialCode, nationalNumber, e164, isValid. */
|
|
34
|
+
type Value = PhoneFieldValue;
|
|
35
|
+
/** Renders a single country in the dropdown list. */
|
|
36
|
+
type RenderCountryItem = (country: Country) => React.ReactNode;
|
|
37
|
+
/** Renders the selected country in the trigger. */
|
|
38
|
+
type RenderCountryValue = (country: Country) => React.ReactNode;
|
|
39
|
+
/** Class names for Country sub-parts (trigger, popup, searchInput, list, item, etc.). */
|
|
40
|
+
type CountrySlots<Value extends PhoneField.Country = PhoneField.Country> = {
|
|
41
|
+
root?: Combobox.Root.Props<Value>;
|
|
42
|
+
placeholder?: React.HTMLAttributes<HTMLSpanElement>;
|
|
43
|
+
trigger?: Combobox.Trigger.Props;
|
|
44
|
+
value?: Combobox.Value.Props;
|
|
45
|
+
icon?: Combobox.Icon.Props;
|
|
46
|
+
popup?: Combobox.Popup.Props;
|
|
47
|
+
positioner?: Combobox.Positioner.Props;
|
|
48
|
+
searchInput?: Combobox.Input.Props;
|
|
49
|
+
list?: Combobox.List.Props;
|
|
50
|
+
item?: Combobox.Item.Props;
|
|
51
|
+
empty?: Combobox.Empty.Props;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Props for `PhoneField.Root`. Extends div. Use `value`/`onValueChange` for controlled mode,
|
|
55
|
+
* or `defaultValue`/`defaultCountry` for uncontrolled. Set `name` to serialize value into FormData.
|
|
56
|
+
*/
|
|
57
|
+
type RootProps = Omit<React.ComponentPropsWithoutRef<"div">, "defaultValue"> & {
|
|
58
|
+
value?: Value;
|
|
59
|
+
defaultValue?: Value;
|
|
60
|
+
onValueChange?: (value: Value) => void;
|
|
61
|
+
defaultCountry?: CountryCodeValue;
|
|
62
|
+
countries?: readonly CountryCodeValue[];
|
|
63
|
+
lang?: Lang;
|
|
64
|
+
name?: string;
|
|
65
|
+
formatOnType?: boolean;
|
|
66
|
+
};
|
|
67
|
+
/** Props for `PhoneField.Country`: label, placeholders, icon, and `slots` for styling. */
|
|
68
|
+
type CountryProps = {
|
|
69
|
+
placeholder?: React.ReactNode;
|
|
70
|
+
noResultsText?: React.ReactNode;
|
|
71
|
+
inputPlaceholder?: string;
|
|
72
|
+
icon?: React.ReactNode;
|
|
73
|
+
slots?: CountrySlots;
|
|
74
|
+
renderCountryItem?: RenderCountryItem;
|
|
75
|
+
renderCountryValue?: RenderCountryValue;
|
|
76
|
+
};
|
|
77
|
+
/** Props for `PhoneField.Input`. Extends Base UI Input (className, onValueChange, etc.). */
|
|
78
|
+
type InputProps = Input.Props;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export { PhoneField, PhoneFieldCountry, PhoneFieldCountryCodeValue, PhoneFieldCountryMap, PhoneFieldCountryName, PhoneFieldLang, PhoneFieldValue };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{getCountriesMap as e,toAvailableCountries as t,resolveCountry as n,buildValue as o,defaultCountrySearchText as r}from"./chunk-ERF62DTM.js";import{Combobox as i}from"@base-ui/react/combobox";import{Input as l}from"@base-ui/react/input";import a from"react";import{jsx as u,jsxs as s}from"react/jsx-runtime";function c(...e){return e.filter(Boolean).join(" ")}var d=a.createContext(null);function f(){const e=a.useContext(d);if(!e)throw new Error("PhoneField compound components must be used inside <PhoneField.Root>.");return e}function m(e){return s("svg",{width:"8",height:"12",viewBox:"0 0 8 12",fill:"none",stroke:"currentColor",strokeWidth:"1.5",...e,children:[u("title",{children:"Arrow"}),u("path",{d:"M0.5 4.5L4 1.5L7.5 4.5"}),u("path",{d:"M0.5 7.5L4 10.5L7.5 7.5"})]})}function p(...e){return t=>{for(const n of e)n&&("function"==typeof n?n(t):n.current=t)}}var h={Root:function({value:r,defaultValue:i,onValueChange:l,defaultCountry:c,countries:f,lang:m,name:p,formatOnType:h=!0,children:y,className:v,...g}){const C=a.useMemo(()=>e(m),[m]),b=a.useMemo(()=>t(C,f),[C,f]),N=n(b,c),[x,I]=a.useState(i??o(N,"",h)),w=r??x,V=n(b,w.countryIso2),P=o(V,w.nationalNumber,h),R=(e,t)=>{const n=o(e,t,h);void 0===r&&I(n),l?.(n)};return u(d.Provider,{value:{value:P,selectedCountry:V,availableCountries:b,setCountry:e=>R(e,P.nationalNumber),setNumber:e=>R(V,e)},children:s("div",{className:v,...g,children:[y,p?u("input",{type:"hidden",name:p,value:JSON.stringify(P)}):null]})})},Country:function({placeholder:e="Select country",noResultsText:t="No countries found",inputPlaceholder:n="Search country",icon:o,slots:l,renderCountryItem:a,renderCountryValue:c}){const{selectedCountry:d,availableCountries:p,setCountry:h}=f(),y=p.find(e=>e.iso2===d.iso2)??p[0];return s(i.Root,{...l?.root,items:p,value:y,itemToStringLabel:r,onValueChange:e=>{e&&h(e)},isItemEqualToValue:(e,t)=>e.iso2===t.iso2,children:[s(i.Trigger,{...l?.trigger,children:[u(i.Value,{...l?.value,placeholder:e,children:t=>t?c?.(t)??`${t.flag?`${t.flag} `:""}${t.name} (${t.dialCode})`:e}),u(i.Icon,{...l?.icon,children:o??u(m,{})})]}),u(i.Portal,{children:u(i.Positioner,{align:"start",sideOffset:4,...l?.positioner,children:s(i.Popup,{...l?.popup,children:[u(i.Input,{...l?.searchInput,placeholder:n,"aria-label":n}),u(i.Empty,{...l?.empty,children:t}),u(i.List,{...l?.list,children:e=>u(i.Item,{value:e,...l?.item,children:a?.(e)??s("div",{className:"flex items-center justify-between gap-4",children:[s("span",{className:"truncate",children:[e.flag?`${e.flag} `:"",e.name]}),s("span",{className:"text-xs opacity-70",children:[e.iso2," · ",e.dialCode]})]})},e.iso2)})]})})})]})},Input:({className:e,onValueChange:t,type:n="text",onKeyDown:o,ref:r,...i})=>{const{value:s,setNumber:d}=f(),m=a.useRef(null),h="h-10 rounded-md border border-zinc-300 px-3 flex-1 outline-none focus:border-zinc-500",y="function"==typeof e?t=>c(h,e(t)):c(h,e);return u(l,{...i,ref:p(r,m),type:n,inputMode:"tel",autoComplete:"tel",pattern:"[0-9]*",className:y,value:s.nationalNumber,onKeyDown:e=>{if("Backspace"===e.key){const t=m.current;if(!t)return;const n=t.selectionStart??0;if(n===(t.selectionEnd??0)&&n>0){const o=t.value[n-1];if(o&&/\D/.test(o)){e.preventDefault();const o=function(e,t){let n=t;for(;n>0&&/\D/.test(e[n-1]??"");)n--;return n-1}(t.value,n);if(o>=0){const e=function(e,t){return e.slice(0,t)+e.slice(t+1)}(t.value,o);d(e),requestAnimationFrame(()=>{t.setSelectionRange(o,o)})}}}}o?.(e)},onValueChange:(e,n)=>{d(e),t?.(e,n)}})}};export{h as PhoneField};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { CountryCode } from 'libphonenumber-js/min';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Country descriptor used by the country picker: ISO2 code, display name, dial code, and optional flag emoji.
|
|
5
|
+
*/
|
|
6
|
+
type PhoneFieldCountry = {
|
|
7
|
+
iso2: CountryCode;
|
|
8
|
+
name: string;
|
|
9
|
+
dialCode: string;
|
|
10
|
+
flag?: string;
|
|
11
|
+
};
|
|
12
|
+
/** Read-only map of ISO2 country code to `PhoneFieldCountry`. */
|
|
13
|
+
type PhoneFieldCountryMap = ReadonlyMap<CountryCode, PhoneFieldCountry>;
|
|
14
|
+
/** ISO2 country code (e.g. `"US"`, `"GB"`). */
|
|
15
|
+
type PhoneFieldCountryCodeValue = CountryCode;
|
|
16
|
+
/** Alias for ISO2 country code. */
|
|
17
|
+
type PhoneFieldCountryName = CountryCode;
|
|
18
|
+
/** BCP 47 locale string or list of locale strings for country display names and sorting. */
|
|
19
|
+
type PhoneFieldLang = string | readonly string[];
|
|
20
|
+
/**
|
|
21
|
+
* Emitted and controlled value shape: country, national number, E.164, and validity.
|
|
22
|
+
* Used as the value/onValueChange payload and when reading from FormData.
|
|
23
|
+
*/
|
|
24
|
+
type PhoneFieldValue = {
|
|
25
|
+
countryIso2: CountryCode;
|
|
26
|
+
countryDialCode: string;
|
|
27
|
+
nationalNumber: string;
|
|
28
|
+
e164: string | null;
|
|
29
|
+
isValid: boolean;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export type { PhoneFieldCountry as P, PhoneFieldCountryMap as a, PhoneFieldCountryCodeValue as b, PhoneFieldCountryName as c, PhoneFieldLang as d, PhoneFieldValue as e };
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import * as libphonenumber_js_min from 'libphonenumber-js/min';
|
|
2
|
+
import { CountryCode } from 'libphonenumber-js/min';
|
|
3
|
+
import { e as PhoneFieldValue, d as PhoneFieldLang, a as PhoneFieldCountryMap, P as PhoneFieldCountry, b as PhoneFieldCountryCodeValue } from './types-BPc8XSky.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Normalizes a BCP 47 locale (string or array) to a single canonical locale string. Returns `"en"` when missing or invalid.
|
|
7
|
+
*/
|
|
8
|
+
declare function normalizeLang(lang?: PhoneFieldLang): any;
|
|
9
|
+
/**
|
|
10
|
+
* Returns a cached map of ISO2 → PhoneFieldCountry for the given locale. Used for country names and sorting.
|
|
11
|
+
*/
|
|
12
|
+
declare function getCountriesMap(lang?: PhoneFieldLang): PhoneFieldCountryMap;
|
|
13
|
+
/** Default country code used when none is specified (e.g. "US"). */
|
|
14
|
+
declare const DEFAULT_COUNTRY: CountryCode;
|
|
15
|
+
/** Returns the default countries map for locale "en". */
|
|
16
|
+
declare function getDefaultCountriesMap(): PhoneFieldCountryMap;
|
|
17
|
+
/** Strips all non-digit characters from a string. */
|
|
18
|
+
declare function onlyDigits(value: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Filters a countries map to the given ISO2 codes, or returns all countries if none provided.
|
|
21
|
+
* @throws If the resulting list is empty.
|
|
22
|
+
*/
|
|
23
|
+
declare function toAvailableCountries(countriesMap: PhoneFieldCountryMap, countries?: readonly PhoneFieldCountryCodeValue[]): PhoneFieldCountry[];
|
|
24
|
+
/**
|
|
25
|
+
* Resolves an ISO2 code to a country from the available list. Falls back to US if present, else first country.
|
|
26
|
+
* @throws If availableCountries is empty.
|
|
27
|
+
*/
|
|
28
|
+
declare function resolveCountry(availableCountries: readonly PhoneFieldCountry[], iso2?: CountryCode): PhoneFieldCountry;
|
|
29
|
+
/**
|
|
30
|
+
* Builds a PhoneFieldValue from country, raw national number string, and formatOnType flag.
|
|
31
|
+
* When formatOnType is true, national number is formatted as-you-type.
|
|
32
|
+
*/
|
|
33
|
+
declare function buildValue(country: PhoneFieldCountry, rawNumber: string, formatOnType: boolean): PhoneFieldValue;
|
|
34
|
+
/** Default search text for a country (name, iso2, dialCode) used by the combobox. */
|
|
35
|
+
declare function defaultCountrySearchText(country: PhoneFieldCountry): string;
|
|
36
|
+
/**
|
|
37
|
+
* Parses a PhoneFieldValue or E.164 string into a libphonenumber PhoneNumber.
|
|
38
|
+
* Use for formatNational(), formatInternational(), getURI(). Options.defaultCountry for national-number strings.
|
|
39
|
+
*/
|
|
40
|
+
declare function parsePhoneField(value: string | PhoneFieldValue, options?: {
|
|
41
|
+
defaultCountry?: CountryCode;
|
|
42
|
+
}): libphonenumber_js_min.PhoneNumber | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* Returns whether the value is a valid phone number. Accepts PhoneFieldValue or E.164 string.
|
|
45
|
+
* Options.defaultCountry for national-number strings.
|
|
46
|
+
*/
|
|
47
|
+
declare function isValidPhoneField(value: string | PhoneFieldValue, options?: {
|
|
48
|
+
defaultCountry?: CountryCode;
|
|
49
|
+
}): boolean;
|
|
50
|
+
/** Type guard: true if the value has the PhoneFieldValue shape. */
|
|
51
|
+
declare function isPhoneFieldValue(value: unknown): value is PhoneFieldValue;
|
|
52
|
+
/**
|
|
53
|
+
* Reads a serialized PhoneField.Value from FormData (JSON string). Returns null if missing or invalid.
|
|
54
|
+
*/
|
|
55
|
+
declare function fromFormData(formData: FormData, name: string): PhoneFieldValue | null;
|
|
56
|
+
/**
|
|
57
|
+
* Helper facade for parse, isValid, fromFormData, getCountries, and default countries map.
|
|
58
|
+
* Use from "phonefield/utils" on client or server.
|
|
59
|
+
*/
|
|
60
|
+
declare const PhoneFieldUtils: {
|
|
61
|
+
parse: typeof parsePhoneField;
|
|
62
|
+
isValid: typeof isValidPhoneField;
|
|
63
|
+
fromFormData: typeof fromFormData;
|
|
64
|
+
getCountries: typeof getCountriesMap;
|
|
65
|
+
readonly countries: PhoneFieldCountryMap;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export { DEFAULT_COUNTRY, PhoneFieldUtils, buildValue, defaultCountrySearchText, fromFormData, getCountriesMap, getDefaultCountriesMap, isPhoneFieldValue, isValidPhoneField, normalizeLang, onlyDigits, parsePhoneField, resolveCountry, toAvailableCountries };
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{DEFAULT_COUNTRY,PhoneFieldUtils,buildValue,defaultCountrySearchText,fromFormData,getCountriesMap,getDefaultCountriesMap,isPhoneFieldValue,isValidPhoneField,normalizeLang,onlyDigits,parsePhoneField,resolveCountry,toAvailableCountries}from"./chunk-ERF62DTM.js";
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "phonefield",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"description": "Composable phone field primitive built with Base UI and libphonenumber-js.",
|
|
9
|
+
"author": "damianricobelli",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/damianricobelli/phonefield.git",
|
|
14
|
+
"directory": "package"
|
|
15
|
+
},
|
|
16
|
+
"homepage": "https://phonefield.vercel.app",
|
|
17
|
+
"sideEffects": false,
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"type": "module",
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"import": "./dist/index.js"
|
|
27
|
+
},
|
|
28
|
+
"./utils": {
|
|
29
|
+
"types": "./dist/utils.d.ts",
|
|
30
|
+
"import": "./dist/utils.js"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"react": ">=18",
|
|
35
|
+
"react-dom": ">=18"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@base-ui/react": "^1.2.0",
|
|
39
|
+
"libphonenumber-js": "^1.12.38"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@testing-library/dom": "^10.4.1",
|
|
43
|
+
"@testing-library/react": "^16.3.2",
|
|
44
|
+
"@types/react": "^19.2.14",
|
|
45
|
+
"@types/react-dom": "^19.2.3",
|
|
46
|
+
"terser": "^5.46.0",
|
|
47
|
+
"tsup": "^8.5.1",
|
|
48
|
+
"typescript": "^5.9.3",
|
|
49
|
+
"vitest": "^4.0.18"
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "tsup",
|
|
53
|
+
"dev": "tsup --watch",
|
|
54
|
+
"typecheck": "tsc --noEmit",
|
|
55
|
+
"test": "vitest run"
|
|
56
|
+
}
|
|
57
|
+
}
|