@nexdom/uimed-vue 2.0.0-beta.42 → 2.0.0-beta.43

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.
@@ -463,8 +463,8 @@ declare const __VLS_export$16: import("vue", { with: { "resolution-mode": "impor
463
463
  "onUpdate:modelValue"?: ((value: string) => any) | undefined;
464
464
  }>, {
465
465
  variant: TextFieldVariant;
466
- type: TextFieldType;
467
466
  clearable: boolean;
467
+ type: TextFieldType;
468
468
  }, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, false, {}, any>;
469
469
  //#endregion
470
470
  //#region src/components/inputs/checkbox/types.d.ts
@@ -652,7 +652,9 @@ type MaskFieldVariant = TextFieldVariant;
652
652
  * Masks the library provides:
653
653
  *
654
654
  * - `cpf`: `###.###.###-##` (e.g. `123.456.789-09`);
655
- * - `cnpj`: `##.###.###/####-##` (e.g. `12.345.678/0001-95`);
655
+ * - `cnpj`: `##.###.###/####-##`, where the first 12 positions also accept
656
+ * letters, typed in uppercase or lowercase and kept in uppercase (e.g.
657
+ * `12.345.678/0001-95` or the alphanumeric `12.ABC.345/01DE-35`);
656
658
  * - `cep`: `#####-###` (e.g. `01310-100`);
657
659
  * - `phone`: `(##) #####-####` (e.g. `(11) 91234-5678`);
658
660
  * - `date`: `##/##/####` (e.g. `31/12/2026`), formatting only.
@@ -691,14 +693,21 @@ type MaskFieldProps = {
691
693
  * inserted automatically (e.g. `####-##/####` or `Nº ####`). A custom mask
692
694
  * must contain at least one `#`.
693
695
  *
694
- * Only digits are accepted, up to the number of `#` in the mask, and the
695
- * `v-model` holds only the digits (e.g. `12345678909` for `cpf`). A literal
696
- * the user could also type, such as a fixed digit (`0800 ###-####`), isn't
697
- * supported: where the literal is expected, the same character is read as
698
- * the literal.
696
+ * Only digits are accepted, up to the number of `#` in the mask, except in
697
+ * the first 12 positions of `cnpj`, which also accept letters (A–Z, without
698
+ * accents, typed in uppercase or lowercase) for the alphanumeric CNPJ (only
699
+ * with `cnpj`: the custom mask `##.###.###/####-##` accepts only digits). The
700
+ * `v-model` holds only these characters, with letters in uppercase (e.g.
701
+ * `12345678909` for `cpf`, and `12345678000195` or `12ABC34501DE35` for
702
+ * `cnpj`). A literal the user could also type, such as a fixed digit
703
+ * (`0800 ###-####`), isn't supported: where the literal is expected, the
704
+ * same character is read as the literal.
705
+ *
706
+ * Editing in the middle of the value shifts the characters after it, and one
707
+ * that doesn't fit its new position (e.g. a letter of `cnpj` shifted into
708
+ * the last 2 positions) is discarded.
699
709
  *
700
- * The `cpf` and `cnpj` masks don't validate check digits, and `cnpj` only
701
- * accepts digits (not the alphanumeric CNPJ).
710
+ * The `cpf` and `cnpj` masks don't validate check digits.
702
711
  *
703
712
  * Changing it keeps the `v-model`: a value that doesn't fit the new mask
704
713
  * (e.g. longer than it) is displayed cut and fails validation with "Valor
@@ -738,7 +747,8 @@ type MaskFieldProps = {
738
747
  label?: string;
739
748
  /**
740
749
  * Field placeholder. Defaults to the mask, with `0` in place of each `#`,
741
- * e.g. `000.000.000-00` for `cpf` and `Nº 0000` for `Nº ####`.
750
+ * e.g. `000.000.000-00` for `cpf`, `00.000.000/0000-00` for `cnpj` and
751
+ * `Nº 0000` for `Nº ####`.
742
752
  */
743
753
  placeholder?: string;
744
754
  /**
@@ -755,9 +765,10 @@ type MaskFieldProps = {
755
765
  //#endregion
756
766
  //#region src/components/inputs/mask-field/mask-field.vue.d.ts
757
767
  /**
758
- * Text field that masks the value while the user types, such as CPF, CNPJ,
759
- * CEP, phone or a custom mask. Its value holds only the digits, without the
760
- * mask's literals.
768
+ * Text field that masks the value while the user types, such as CPF, CNPJ
769
+ * (numeric or alphanumeric), CEP, phone or a custom mask. Its value holds only
770
+ * the typed characters, without the mask's literals and with letters in
771
+ * uppercase.
761
772
  *
762
773
  * @example
763
774
  * ```vue
@@ -1917,79 +1917,96 @@ var date_time_field_default = /* @__PURE__ */ defineComponent({
1917
1917
  //#endregion
1918
1918
  //#region src/composables/inputs/mask-field.ts
1919
1919
  /**
1920
- * Masks of the presets. Our preset names always map to these masks, never to
1921
- * Vuetify's own presets (e.g. its American `phone`).
1920
+ * Masks of the presets, as Vuetify reads them: `#` is a digit and `N` is a
1921
+ * letter or a digit, with letters converted to uppercase. Our preset names
1922
+ * always map to these masks, never to Vuetify's own presets (e.g. its American
1923
+ * `phone`).
1922
1924
  */
1923
1925
  const maskFieldPresets = {
1924
1926
  cpf: "###.###.###-##",
1925
- cnpj: "##.###.###/####-##",
1927
+ cnpj: "NN.NNN.NNN/NNNN-##",
1926
1928
  cep: "#####-###",
1927
1929
  phone: "(##) #####-####",
1928
1930
  date: "##/##/####"
1929
1931
  };
1930
1932
  /**
1931
- * Returns the mask of a preset, or the given mask itself when it's a custom
1932
- * one.
1933
+ * Returns the mask as Vuetify reads it: the mask of a preset, or the given mask
1934
+ * itself, escaped, when it's a custom one.
1933
1935
  *
1934
1936
  * It takes any string, as the `mask` prop may get one through a cast or from
1935
1937
  * JavaScript: a string that isn't a preset is taken as the mask.
1936
1938
  */
1937
1939
  function resolveMask(mask) {
1938
- return isMaskFieldPreset(mask) ? maskFieldPresets[mask] : mask;
1940
+ return isMaskFieldPreset(mask) ? maskFieldPresets[mask] : toVuetifyMask(mask);
1939
1941
  }
1940
1942
  /**
1941
- * Returns a mask as Vuetify reads it. `#` is our only token, but Vuetify always
1942
- * adds its own tokens (`A`, `a`, `N`, `n` and `X`) and its escape (`\`), so
1943
- * these characters are escaped to stay literals.
1943
+ * Returns a custom mask as Vuetify reads it. `#` is the only token of custom
1944
+ * masks, but Vuetify always adds its own tokens (`A`, `a`, `N`, `n` and `X`)
1945
+ * and its escape (`\`), so these characters are escaped to stay literals.
1944
1946
  */
1945
1947
  function toVuetifyMask(mask) {
1946
1948
  return mask.replaceAll(/[AaNnX\\]/g, String.raw`\$&`);
1947
1949
  }
1948
1950
  /**
1949
- * Returns the default placeholder of a mask: the mask with `0` in place of each
1950
- * `#`, keeping its literals (e.g. `000.000.000-00` for `cpf`).
1951
+ * Returns the tokens of a mask as Vuetify reads it (see {@link resolveMask}),
1952
+ * in order, without its literals (e.g. `NNNNNNNNNNNN##` for `cnpj`).
1953
+ */
1954
+ function getMaskTokens(mask) {
1955
+ return mask.replaceAll(/\\.|[^#N]/g, "");
1956
+ }
1957
+ /**
1958
+ * Returns the default placeholder of a mask as Vuetify reads it (see
1959
+ * {@link resolveMask}): the mask with `0` in place of each token, keeping its
1960
+ * literals (e.g. `000.000.000-00` for `cpf` and `Nº 0000` for `Nº ####`).
1951
1961
  */
1952
1962
  function getMaskPlaceholder(mask) {
1953
- return mask.replaceAll("#", "0");
1963
+ return mask.replaceAll(/\\(.)|[#N]/g, (_token, literal) => literal ?? "0");
1954
1964
  }
1955
1965
  function isMaskFieldPreset(mask) {
1956
1966
  return Object.hasOwn(maskFieldPresets, mask);
1957
1967
  }
1958
1968
  /**
1959
- * Keeps the input masked while the user edits it, emitting only the digits
1960
- * (Vuetify's `unmask`).
1969
+ * Keeps the input masked while the user edits it, emitting only the
1970
+ * characters of the tokens (Vuetify's `unmask`), with letters in uppercase.
1961
1971
  *
1962
- * A `v-model` out of the mask's format (masked, or with characters or length
1963
- * the mask doesn't accept) is displayed normalized, without being emitted, and
1964
- * validated as it is, so a value that doesn't fit the mask fails validation.
1972
+ * A `v-model` out of the mask's format (masked, with lowercase letters, or with
1973
+ * characters or length the mask doesn't accept) is displayed normalized,
1974
+ * without being emitted, and validated as it is, so a value that doesn't fit
1975
+ * the mask fails validation.
1965
1976
  */
1966
1977
  function useMaskField(props, model) {
1967
1978
  const mask = computed(() => resolveMask(props.mask));
1968
- const digitCount = computed(() => mask.value.split("#").length - 1);
1979
+ const tokens = computed(() => getMaskTokens(mask.value));
1980
+ const acceptsLetters = computed(() => tokens.value.includes("N"));
1969
1981
  const vuetifyMask = useMask({ get mask() {
1970
1982
  return {
1971
- mask: toVuetifyMask(mask.value),
1983
+ mask: mask.value,
1972
1984
  tokens: {}
1973
1985
  };
1974
1986
  } });
1975
1987
  const displayValue = computed(() => vuetifyMask.mask(unmask(model.value)));
1976
1988
  const placeholder = computed(() => props.placeholder ?? getMaskPlaceholder(mask.value));
1989
+ const inputMode = computed(() => acceptsLetters.value ? "text" : "numeric");
1990
+ const autocapitalize = computed(() => acceptsLetters.value ? "characters" : void 0);
1977
1991
  const defaultRules = useRules(props);
1978
1992
  const rules = computed(() => [
1979
1993
  ...defaultRules.value,
1980
- (value) => !value || !vuetifyMask.isValid(value) || isComplete(value) || "Valor incompleto",
1981
- (value) => !value || vuetifyMask.isValid(value) || "Valor inválido"
1994
+ (value) => !value || !isValid(value) || isComplete(value) || "Valor incompleto",
1995
+ (value) => !value || isValid(value) || "Valor inválido"
1982
1996
  ]);
1983
1997
  function unmask(text) {
1984
1998
  return vuetifyMask.unmask(text) ?? "";
1985
1999
  }
2000
+ function isValid(value) {
2001
+ return unmask(value).toUpperCase() === unmask(vuetifyMask.mask(value));
2002
+ }
1986
2003
  function isComplete(value) {
1987
- return unmask(vuetifyMask.mask(value)).length === digitCount.value;
2004
+ return unmask(vuetifyMask.mask(value)).length === tokens.value.length;
1988
2005
  }
1989
2006
  /**
1990
2007
  * Returns the position in a masked text right after the given number of
1991
- * digits, skipping the literals after it unless the user deleted backwards
1992
- * (as Vuetify's mask input does).
2008
+ * characters of the value, skipping the literals after it unless the user
2009
+ * deleted backwards (as Vuetify's mask input does).
1993
2010
  */
1994
2011
  function findCaret(masked, valueLength, deletedBackwards) {
1995
2012
  let caret = 0;
@@ -2019,6 +2036,8 @@ function useMaskField(props, model) {
2019
2036
  return {
2020
2037
  displayValue,
2021
2038
  placeholder,
2039
+ inputMode,
2040
+ autocapitalize,
2022
2041
  rules,
2023
2042
  onInput,
2024
2043
  onCompositionEnd
@@ -2087,7 +2106,7 @@ var mask_field_default = /* @__PURE__ */ defineComponent({
2087
2106
  const modelValue = useModel(__props, "modelValue");
2088
2107
  const props = __props;
2089
2108
  const vuetifyVariant = useTextFieldVariant(() => props.variant);
2090
- const { displayValue, placeholder, rules, onInput, onCompositionEnd } = useMaskField(props, modelValue);
2109
+ const { displayValue, placeholder, inputMode, autocapitalize, rules, onInput, onCompositionEnd } = useMaskField(props, modelValue);
2091
2110
  function keepFieldControlled() {}
2092
2111
  function clear() {
2093
2112
  modelValue.value = "";
@@ -2108,7 +2127,8 @@ var mask_field_default = /* @__PURE__ */ defineComponent({
2108
2127
  hint: props.hint,
2109
2128
  clearable: props.clearable,
2110
2129
  type: "text",
2111
- inputmode: "numeric",
2130
+ inputmode: unref(inputMode),
2131
+ autocapitalize: unref(autocapitalize),
2112
2132
  "onUpdate:modelValue": keepFieldControlled,
2113
2133
  onInput: unref(onInput),
2114
2134
  onCompositionend: unref(onCompositionEnd),
@@ -2130,6 +2150,8 @@ var mask_field_default = /* @__PURE__ */ defineComponent({
2130
2150
  "placeholder",
2131
2151
  "hint",
2132
2152
  "clearable",
2153
+ "inputmode",
2154
+ "autocapitalize",
2133
2155
  "onInput",
2134
2156
  "onCompositionend"
2135
2157
  ]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexdom/uimed-vue",
3
- "version": "2.0.0-beta.42",
3
+ "version": "2.0.0-beta.43",
4
4
  "description": "A ui framework for NEXDOM applications.",
5
5
  "keywords": [
6
6
  "lib",