@brightweblabs/ui 1.4.8 → 1.4.10

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@brightweblabs/ui",
3
3
  "private": false,
4
- "version": "1.4.8",
4
+ "version": "1.4.10",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
7
7
  "files": [
@@ -78,7 +78,7 @@
78
78
  "recharts": "^2.15.4",
79
79
  "sonner": "^2.0.7",
80
80
  "tailwind-merge": "^3.6.0",
81
- "@brightweblabs/theme": "0.7.4"
81
+ "@brightweblabs/theme": "0.8.0"
82
82
  },
83
83
  "peerDependencies": {
84
84
  "lucide-react": "^1.8.0",
@@ -23,21 +23,26 @@ function flagEmoji(iso2: string) {
23
23
  return iso2.toUpperCase().split("").map((character) => String.fromCodePoint(0x1f1e6 - 0x41 + character.charCodeAt(0))).join("");
24
24
  }
25
25
 
26
- export function PhoneInput({ value, onChange, defaultCountry = "pt", disabled = false, className, placeholder = "912 345 678", ...inputProps }: PhoneInputProps) {
26
+ function normalizePhoneValue(phone: string, dialCode: string) {
27
+ return phone === `+${dialCode}` ? "" : phone;
28
+ }
29
+
30
+ export function PhoneInput({ value, onChange, defaultCountry = "pt", disabled = false, className, placeholder = "912 345 678", name, "aria-describedby": ariaDescribedBy, ...inputProps }: PhoneInputProps) {
27
31
  const inputRef = useRef<HTMLInputElement | null>(null);
28
32
  const triggerRef = useRef<HTMLButtonElement | null>(null);
29
33
  const dropdownRef = useRef<HTMLDivElement | null>(null);
30
34
  const optionRefs = useRef<Array<HTMLButtonElement | null>>([]);
31
35
  const countryListId = useId();
36
+ const phonePrefixId = useId();
32
37
  const [open, setOpen] = useState(false);
33
38
  const [search, setSearch] = useState("");
34
39
  const [activeIndex, setActiveIndex] = useState(0);
35
40
 
36
- const { inputValue, handlePhoneValueChange, country, setCountry } = usePhoneInput({
41
+ const { phone, inputValue, handlePhoneValueChange, country, setCountry } = usePhoneInput({
37
42
  defaultCountry,
38
43
  value,
39
- forceDialCode: true,
40
- onChange: ({ phone }) => onChange(phone),
44
+ disableDialCodeAndPrefix: true,
45
+ onChange: ({ phone: nextPhone, country: nextCountry }) => onChange(normalizePhoneValue(nextPhone, nextCountry.dialCode)),
41
46
  inputRef,
42
47
  });
43
48
 
@@ -123,7 +128,7 @@ export function PhoneInput({ value, onChange, defaultCountry = "pt", disabled =
123
128
  aria-controls={countryListId}
124
129
  aria-expanded={open}
125
130
  aria-haspopup="listbox"
126
- aria-label="Choose country code"
131
+ aria-label={`Choose country code, current ${country.name} +${country.dialCode}`}
127
132
  >
128
133
  <span className="text-body-lg leading-none">{flagEmoji(country.iso2)}</span>
129
134
  <svg className="size-2.5 text-foreground/40" viewBox="0 0 10 6" fill="none" aria-hidden>
@@ -181,7 +186,9 @@ export function PhoneInput({ value, onChange, defaultCountry = "pt", disabled =
181
186
  ) : null}
182
187
 
183
188
  <span className="h-4 w-px shrink-0 bg-foreground/15" />
184
- <input {...inputProps} ref={inputRef} value={inputValue} onChange={handlePhoneValueChange} disabled={disabled} placeholder={placeholder} type="tel" className="h-7 flex-1 border-0 bg-transparent pl-2 text-body text-foreground outline-none placeholder:text-foreground-muted-accessible disabled:pointer-events-none disabled:opacity-100" />
189
+ <span id={phonePrefixId} className="select-none pl-2 text-body text-foreground">+{country.dialCode}</span>
190
+ <input {...inputProps} aria-describedby={[ariaDescribedBy, phonePrefixId].filter(Boolean).join(" ")} ref={inputRef} value={inputValue} onChange={handlePhoneValueChange} disabled={disabled} placeholder={placeholder} type="tel" className="h-7 flex-1 border-0 bg-transparent pl-1 text-body text-foreground outline-none placeholder:text-foreground-muted-accessible disabled:pointer-events-none disabled:opacity-100" />
191
+ {name ? <input type="hidden" name={name} value={normalizePhoneValue(phone, country.dialCode)} disabled={disabled} form={inputProps.form} /> : null}
185
192
  </div>
186
193
  );
187
194
  }