innoboxrr-react-form-elements 3.5.0 → 3.6.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "innoboxrr-react-form-elements",
3
- "version": "3.5.0",
3
+ "version": "3.6.0",
4
4
  "description": "Gemelo React de innoboxrr-form-elements: los mismos componentes, los mismos nombres y el mismo contrato, con diálogos, drawers, menús, avisos y paleta de comandos.",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -53,7 +53,7 @@
53
53
  "@tinymce/tinymce-react": "^6.3.0",
54
54
  "@uiw/react-codemirror": "^4.25.11",
55
55
  "@yaireo/tagify": "^4.38.0",
56
- "innoboxrr-form-core": "^2.7.0",
56
+ "innoboxrr-form-core": "^2.8.0",
57
57
  "innoboxrr-maskjs": "^2.0.0",
58
58
  "react-colorful": "^5.8.1",
59
59
  "react-phone-number-input": "^3.4.18",
@@ -1,6 +1,7 @@
1
- import { useState } from 'react'
1
+ import { useId, useState } from 'react'
2
2
  import PhoneInput, { isValidPhoneNumber, parsePhoneNumber } from 'react-phone-number-input'
3
- import Field from './internal/Field.jsx'
3
+ import 'react-phone-number-input/style.css'
4
+ import useTheme, { joinClasses } from './internal/useTheme.js'
4
5
 
5
6
  /**
6
7
  * Gemelo de CountrySelectInputComponent.vue.
@@ -15,29 +16,40 @@ import Field from './internal/Field.jsx'
15
16
  * emitía `change` en Vue, para que el formulario que ya lo consumía siga
16
17
  * funcionando igual.
17
18
  *
18
- * Los estilos van una vez por aplicación:
19
- *
20
- * import 'react-phone-number-input/style.css'
19
+ * La hoja de la librería la importa el componente, igual que el de Vue. Antes
20
+ * la tenía que importar la aplicación y, si no lo hacía, el selector de país y
21
+ * el campo salían como controles nativos sin forma. El aspecto sale del tema
22
+ * (`phone`, `phoneInvalid`).
21
23
  */
22
24
  export default function CountrySelectInputComponent({
23
- wrapperClass = 'fe-mb',
24
- containerClass = 'fe-inline fe-w-full',
25
- labelClass = 'ml-2 text-sm font-medium text-gray-900 dark:text-white',
25
+ // Sin valor, cada una sale de su token del tema.
26
+ wrapperClass = null,
27
+ containerClass = null,
28
+ labelClass = null,
26
29
  label = '',
27
30
  help = null,
28
31
  defaultPhone = '',
29
32
  defaultCountry = null,
30
33
  disabled = false,
31
34
  name = 'telephone',
35
+ id = null,
32
36
  placeholder = 'Ingresa un número telefónico',
33
37
  validators = null,
34
38
  onCountryChange,
35
39
  ...rest
36
40
  }) {
41
+ const theme = useTheme()
42
+
43
+ // Con el nombre como id, dos teléfonos en la misma página compartían id y
44
+ // la etiqueta del segundo enfocaba el primero.
45
+ const generatedId = useId()
46
+ const inputId = id ?? `${name}-${generatedId}`
47
+
37
48
  const [phone, setPhone] = useState(defaultPhone ? String(defaultPhone) : '')
38
49
  const [country, setCountry] = useState(defaultCountry ?? undefined)
39
50
 
40
51
  const valid = Boolean(phone) && isValidPhoneNumber(phone)
52
+ const invalid = ! valid && phone.length !== 0
41
53
 
42
54
  const announce = (nextPhone, nextCountry) => {
43
55
  const isValid = Boolean(nextPhone) && isValidPhoneNumber(nextPhone)
@@ -53,14 +65,15 @@ export default function CountrySelectInputComponent({
53
65
  }
54
66
 
55
67
  return (
56
- <div className={wrapperClass}>
57
- <div className={containerClass}>
58
- {label ? <label className={labelClass} htmlFor={name}>{label}</label> : null}
68
+ <div className={wrapperClass ?? theme.field}>
69
+ {label ? <label className={labelClass ?? theme.label} htmlFor={inputId}>{label}</label> : null}
59
70
 
71
+ <div className={containerClass ?? theme.fieldInner}>
60
72
  <PhoneInput
61
- id={name}
73
+ id={inputId}
62
74
  name={name}
63
- className={(! valid && phone.length !== 0) ? 'error' : undefined}
75
+ className={joinClasses(theme.phone, invalid && theme.phoneInvalid)}
76
+ aria-invalid={invalid || undefined}
64
77
  international
65
78
  countryCallingCodeEditable={false}
66
79
  defaultCountry={defaultCountry ?? undefined}
@@ -79,9 +92,9 @@ export default function CountrySelectInputComponent({
79
92
  announce(clean, country)
80
93
  }}
81
94
  {...rest} />
82
-
83
- {help ? <p className="fe-text-muted">{help}</p> : null}
84
95
  </div>
96
+
97
+ {help ? <p className="fe-text-muted fe-text-sm">{help}</p> : null}
85
98
  </div>
86
99
  )
87
100
  }