@nexdom/uimed-vue 2.0.0-beta.37 → 2.0.0-beta.39

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.
@@ -134,6 +134,22 @@ interface NavigationMenuItem {
134
134
  action?: () => void;
135
135
  }
136
136
  //#endregion
137
+ //#region src/components/footer/types.d.ts
138
+ /**
139
+ * Props of the footer shown by the {@link Main} component.
140
+ */
141
+ type FooterProps = {
142
+ /**
143
+ * Text shown in the footer, e.g. the application version ("Versão 1.4.2").
144
+ * The footer is hidden when it's empty or omitted.
145
+ */
146
+ description?: string;
147
+ /**
148
+ * Component id to use on automated tests.
149
+ */
150
+ dataTestid?: string;
151
+ };
152
+ //#endregion
137
153
  //#region src/components/main/types.d.ts
138
154
  /**
139
155
  * Props exposed by the {@link Main} component.
@@ -158,6 +174,16 @@ type MainProps = {
158
174
  * Navigation menu properties.
159
175
  */
160
176
  navigationMenu?: NavigationMenuProps;
177
+ /**
178
+ * Footer properties. The footer is fixed at the bottom of the screen and
179
+ * is hidden when it's omitted or its `description` is empty.
180
+ *
181
+ * @example
182
+ * ```vue
183
+ * <u-main :footer="{ description: `Versão ${version}` }" />
184
+ * ```
185
+ */
186
+ footer?: FooterProps;
161
187
  /**
162
188
  * Shows skeleton loaders in place of the user-related parts of the app bar
163
189
  * and of the navigation menu items while their data is being loaded.
@@ -182,8 +208,8 @@ type MainProps = {
182
208
  *
183
209
  * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/main | Main Guide}
184
210
  */
185
- declare const _default$13: typeof __VLS_export$18;
186
- declare const __VLS_export$18: __VLS_WithSlots$11<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<MainProps & {
211
+ declare const _default$13: typeof __VLS_export$19;
212
+ declare const __VLS_export$19: __VLS_WithSlots$11<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<MainProps & {
187
213
  notificationsOpen?: boolean;
188
214
  }, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {
189
215
  "update:notificationsOpen": (value: boolean) => any;
@@ -215,8 +241,8 @@ type __VLS_WithSlots$11<T, S> = T & {
215
241
  *
216
242
  * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/button | Button Guide}
217
243
  */
218
- declare const _default$1: typeof __VLS_export$17;
219
- declare const __VLS_export$17: __VLS_WithSlots$10<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<ButtonProps, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {} & {
244
+ declare const _default$1: typeof __VLS_export$18;
245
+ declare const __VLS_export$18: __VLS_WithSlots$10<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<ButtonProps, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {} & {
220
246
  click: (event: MouseEvent) => any;
221
247
  }, string, import("vue", { with: { "resolution-mode": "import" } }).PublicProps, Readonly<ButtonProps> & Readonly<{
222
248
  onClick?: ((event: MouseEvent) => any) | undefined;
@@ -395,8 +421,8 @@ type AutocompleteFieldProps<T = string, Multiple extends boolean = false> = {
395
421
  *
396
422
  * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/autocomplete-field | AutocompleteField Guide}
397
423
  */
398
- declare const _default: typeof __VLS_export$16;
399
- declare const __VLS_export$16: <T = string, Multiple extends boolean = false>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal$2<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
424
+ declare const _default: typeof __VLS_export$17;
425
+ declare const __VLS_export$17: <T = string, Multiple extends boolean = false>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal$2<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
400
426
  props: import("vue").PublicProps & __VLS_PrettifyLocal$2<(AutocompleteFieldProps<T, Multiple> & {
401
427
  modelValue?: Multiple extends true ? T[] : T;
402
428
  }) & {
@@ -426,8 +452,8 @@ type __VLS_PrettifyLocal$2<T> = (T extends any ? { [K in keyof T]: T[K]; } : { [
426
452
  *
427
453
  * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/text-field | TextField Guide}
428
454
  */
429
- declare const _default$18: typeof __VLS_export$15;
430
- declare const __VLS_export$15: import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<TextFieldProps & {
455
+ declare const _default$19: typeof __VLS_export$16;
456
+ declare const __VLS_export$16: import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<TextFieldProps & {
431
457
  modelValue?: string;
432
458
  }, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {
433
459
  "update:modelValue": (value: string) => any;
@@ -437,8 +463,8 @@ declare const __VLS_export$15: import("vue", { with: { "resolution-mode": "impor
437
463
  "onUpdate:modelValue"?: ((value: string) => any) | undefined;
438
464
  }>, {
439
465
  variant: TextFieldVariant;
440
- type: TextFieldType;
441
466
  clearable: boolean;
467
+ type: TextFieldType;
442
468
  }, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, false, {}, any>;
443
469
  //#endregion
444
470
  //#region src/components/inputs/checkbox/types.d.ts
@@ -489,8 +515,8 @@ type CheckboxProps<T = boolean> = {
489
515
  *
490
516
  * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/checkbox | Checkbox Guide}
491
517
  */
492
- declare const _default$2: typeof __VLS_export$14;
493
- declare const __VLS_export$14: <T = any>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal$1<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
518
+ declare const _default$2: typeof __VLS_export$15;
519
+ declare const __VLS_export$15: <T = any>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal$1<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
494
520
  props: import("vue").PublicProps & __VLS_PrettifyLocal$1<(CheckboxProps<boolean | T> & {
495
521
  modelValue?: T;
496
522
  }) & {
@@ -606,8 +632,8 @@ type DateTimeFieldProps = {
606
632
  *
607
633
  * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/date-time-field | DateTimeField Guide}
608
634
  */
609
- declare const _default$7: typeof __VLS_export$13;
610
- declare const __VLS_export$13: import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<DateTimeFieldProps & {
635
+ declare const _default$7: typeof __VLS_export$14;
636
+ declare const __VLS_export$14: import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<DateTimeFieldProps & {
611
637
  modelValue?: string;
612
638
  }, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {
613
639
  "update:modelValue": (value: string) => any;
@@ -620,6 +646,142 @@ declare const __VLS_export$13: import("vue", { with: { "resolution-mode": "impor
620
646
  type: DateTimeFieldType;
621
647
  }, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, false, {}, any>;
622
648
  //#endregion
649
+ //#region src/components/inputs/mask-field/types.d.ts
650
+ type MaskFieldVariant = TextFieldVariant;
651
+ /**
652
+ * Masks the library provides:
653
+ *
654
+ * - `cpf`: `###.###.###-##` (e.g. `123.456.789-09`);
655
+ * - `cnpj`: `##.###.###/####-##` (e.g. `12.345.678/0001-95`);
656
+ * - `cep`: `#####-###` (e.g. `01310-100`);
657
+ * - `phone`: `(##) #####-####` (e.g. `(11) 91234-5678`);
658
+ * - `date`: `##/##/####` (e.g. `31/12/2026`), formatting only.
659
+ */
660
+ type MaskFieldPreset = "cpf" | "cnpj" | "cep" | "phone" | "date";
661
+ /**
662
+ * A preset name, or the mask itself, where `#` is a digit (0–9) and any other
663
+ * character, letters included, is a literal inserted automatically (e.g.
664
+ * `####-##/####` or `Nº ####`).
665
+ *
666
+ * A custom mask must contain at least one `#`, so a misspelled preset (e.g.
667
+ * `"cpff"`) is a type error.
668
+ *
669
+ * @example
670
+ * ```ts
671
+ * const preset: MaskFieldMask = "cpf";
672
+ * const custom: MaskFieldMask = "####-##/####";
673
+ * const withLetters: MaskFieldMask = "Nº ####";
674
+ * ```
675
+ */
676
+ type MaskFieldMask = MaskFieldPreset | `${string}#${string}`;
677
+ /**
678
+ * Props exposed by the {@link MaskField} component.
679
+ */
680
+ type MaskFieldProps = {
681
+ /**
682
+ * Applies a distinct style variation to the field.
683
+ * One of `primary` or `secondary`.
684
+ * @default "primary"
685
+ */
686
+ variant?: MaskFieldVariant;
687
+ /**
688
+ * Mask applied to the value while the user types. One of the presets
689
+ * (`cpf`, `cnpj`, `cep`, `phone` or `date`), or the mask itself, where `#`
690
+ * is a digit (0–9) and any other character, letters included, is a literal
691
+ * inserted automatically (e.g. `####-##/####` or `Nº ####`). A custom mask
692
+ * must contain at least one `#`.
693
+ *
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.
699
+ *
700
+ * The `cpf` and `cnpj` masks don't validate check digits, and `cnpj` only
701
+ * accepts digits (not the alphanumeric CNPJ).
702
+ *
703
+ * Changing it keeps the `v-model`: a value that doesn't fit the new mask
704
+ * (e.g. longer than it) is displayed cut and fails validation with "Valor
705
+ * inválido".
706
+ */
707
+ mask: MaskFieldMask;
708
+ /**
709
+ * Removes the ability to click or target the field.
710
+ * @default false
711
+ */
712
+ disabled?: boolean;
713
+ /**
714
+ * Displays a loading indicator on the input. The field keeps its label as
715
+ * accessible name and is marked as busy, and assistive technologies ignore
716
+ * the indicator.
717
+ * @default false
718
+ */
719
+ loading?: boolean;
720
+ /**
721
+ * Displays clear action.
722
+ * @default false
723
+ */
724
+ clearable?: boolean;
725
+ /**
726
+ * Prevent value changes.
727
+ * @default false
728
+ */
729
+ readonly?: boolean;
730
+ /**
731
+ * Add `rules` to require field to be filled before form submission.
732
+ * @default false
733
+ */
734
+ required?: boolean;
735
+ /**
736
+ * Field label.
737
+ */
738
+ label?: string;
739
+ /**
740
+ * 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º ####`.
742
+ */
743
+ placeholder?: string;
744
+ /**
745
+ * Field message to show and direct user to fill field correctly.
746
+ *
747
+ * This message will be replaced when there's an error message to be shown.
748
+ */
749
+ hint?: string;
750
+ /**
751
+ * Component id to use on automated tests.
752
+ */
753
+ dataTestid?: string;
754
+ };
755
+ //#endregion
756
+ //#region src/components/inputs/mask-field/mask-field.vue.d.ts
757
+ /**
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.
761
+ *
762
+ * @example
763
+ * ```vue
764
+ * <template>
765
+ * <u-mask-field v-model="cpf" label="CPF" mask="cpf" />
766
+ * <u-mask-field v-model="protocol" label="Protocolo" mask="####-##/####" />
767
+ * </template>
768
+ * ```
769
+ *
770
+ * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/mask-field | MaskField Guide}
771
+ */
772
+ declare const _default$14: typeof __VLS_export$13;
773
+ declare const __VLS_export$13: import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<MaskFieldProps & {
774
+ modelValue?: string;
775
+ }, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {
776
+ "update:modelValue": (value: string) => any;
777
+ }, string, import("vue", { with: { "resolution-mode": "import" } }).PublicProps, Readonly<MaskFieldProps & {
778
+ modelValue?: string;
779
+ }> & Readonly<{
780
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
781
+ }>, {
782
+ variant: MaskFieldVariant;
783
+ }, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, false, {}, any>;
784
+ //#endregion
623
785
  //#region src/components/grid/container/types.d.ts
624
786
  /**
625
787
  * Props exposed by the {@link Container} component.
@@ -753,7 +915,7 @@ type RowProps = {
753
915
  *
754
916
  * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/layout | Row Guide}
755
917
  */
756
- declare const _default$14: typeof __VLS_export$11;
918
+ declare const _default$15: typeof __VLS_export$11;
757
919
  declare const __VLS_export$11: __VLS_WithSlots$8<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<RowProps, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {}, string, import("vue", { with: { "resolution-mode": "import" } }).PublicProps, Readonly<RowProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, false, {}, any>, {
758
920
  default?: (props: {}) => any;
759
921
  }>;
@@ -882,7 +1044,7 @@ type __VLS_WithSlots$6<T, S> = T & {
882
1044
  *
883
1045
  * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/section | Section Guide}
884
1046
  */
885
- declare const _default$16: typeof __VLS_export$8;
1047
+ declare const _default$17: typeof __VLS_export$8;
886
1048
  declare const __VLS_export$8: __VLS_WithSlots$5<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<{}, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {}, string, import("vue", { with: { "resolution-mode": "import" } }).PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, true, {}, any>, {
887
1049
  default?: (props: {}) => any;
888
1050
  }>;
@@ -987,7 +1149,7 @@ interface SectionAction extends ButtonProps {
987
1149
  *
988
1150
  * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/section | Section Guide}
989
1151
  */
990
- declare const _default$15: typeof __VLS_export$7;
1152
+ declare const _default$16: typeof __VLS_export$7;
991
1153
  declare const __VLS_export$7: __VLS_WithSlots$4<import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<SectionProps, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {}, string, import("vue", { with: { "resolution-mode": "import" } }).PublicProps, Readonly<SectionProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, false, {}, any>, {
992
1154
  default?: (props: {}) => any;
993
1155
  }>;
@@ -1062,7 +1224,7 @@ type TableProps = {
1062
1224
  *
1063
1225
  * @see {@link https://nexdom-healthtech.github.io/uimed-vue/guide/components/table | Table Guide}
1064
1226
  */
1065
- declare const _default$17: typeof __VLS_export$6;
1227
+ declare const _default$18: typeof __VLS_export$6;
1066
1228
  declare const __VLS_export$6: import("vue", { with: { "resolution-mode": "import" } }).DefineComponent<TableProps, {}, {}, {}, {}, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, import("vue", { with: { "resolution-mode": "import" } }).ComponentOptionsMixin, {}, string, import("vue", { with: { "resolution-mode": "import" } }).PublicProps, Readonly<TableProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, false, {}, any>;
1067
1229
  //#endregion
1068
1230
  //#region src/components/details/types.d.ts
@@ -1493,4 +1655,4 @@ type __VLS_WithSlots<T, S> = T & {
1493
1655
  };
1494
1656
  };
1495
1657
  //#endregion
1496
- export { _default as UAutocompleteField, _default$1 as UButton, _default$2 as UCheckbox, _default$3 as UColumn, _default$4 as UContainer, _default$5 as UDataSet, _default$6 as UDataSetItem, _default$7 as UDateTimeField, _default$8 as UDetails, _default$9 as UDialog, _default$10 as UForm, _default$11 as UImg, _default$12 as ULink, _default$13 as UMain, _default$14 as URow, _default$15 as USection, _default$16 as USectionContent, _default$17 as UTable, _default$18 as UTextField };
1658
+ export { _default as UAutocompleteField, _default$1 as UButton, _default$2 as UCheckbox, _default$3 as UColumn, _default$4 as UContainer, _default$5 as UDataSet, _default$6 as UDataSetItem, _default$7 as UDateTimeField, _default$8 as UDetails, _default$9 as UDialog, _default$10 as UForm, _default$11 as UImg, _default$12 as ULink, _default$13 as UMain, _default$14 as UMaskField, _default$15 as URow, _default$16 as USection, _default$17 as USectionContent, _default$18 as UTable, _default$19 as UTextField };
@@ -1,7 +1,8 @@
1
1
  import { a as messages, n as owners$1, r as requests, s as useVuetifyColor } from "./use-dialog-Ck2_ZW7T.js";
2
+ import { useMask } from "vuetify";
2
3
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createTextVNode, createVNode, defineComponent, guardReactiveProps, inject, isRef, mergeModels, mergeProps, nextTick, normalizeClass, normalizeProps, onMounted, onScopeDispose, onUnmounted, openBlock, provide, readonly, ref, renderList, renderSlot, resolveDynamicComponent, shallowRef, toDisplayString, toValue, unref, useId, useModel, useSlots, useTemplateRef, watch, withCtx, withKeys, withModifiers } from "vue";
3
4
  import { pt } from "vuetify/locale";
4
- import { VApp, VAppBar, VAppBarNavIcon, VAppBarTitle, VAutocomplete, VAvatar, VBadge, VBtn, VCard, VCardActions, VCardText, VCheckboxBtn, VCol, VCombobox, VContainer, VDataIterator, VDatePicker, VDialog, VDivider, VEmptyState, VExpansionPanel, VExpansionPanelText, VExpansionPanelTitle, VExpansionPanels, VForm, VIcon, VIconBtn, VImg, VList, VListGroup, VListItem, VListItemAction, VListSubheader, VLocaleProvider, VMain, VMenu, VNavigationDrawer, VPagination, VProgressCircular, VProgressLinear, VRow, VSkeletonLoader, VSnackbarQueue, VTable, VTextField, VTimePicker } from "vuetify/components";
5
+ import { VApp, VAppBar, VAppBarNavIcon, VAppBarTitle, VAutocomplete, VAvatar, VBadge, VBtn, VCard, VCardActions, VCardText, VCheckboxBtn, VCol, VCombobox, VContainer, VDataIterator, VDatePicker, VDialog, VDivider, VEmptyState, VExpansionPanel, VExpansionPanelText, VExpansionPanelTitle, VExpansionPanels, VFooter, VForm, VIcon, VIconBtn, VImg, VList, VListGroup, VListItem, VListItemAction, VListSubheader, VLocaleProvider, VMain, VMenu, VNavigationDrawer, VPagination, VProgressCircular, VProgressLinear, VRow, VSkeletonLoader, VSnackbarQueue, VTable, VTextField, VTimePicker } from "vuetify/components";
5
6
  import { formatDateTime, isEmail, isEmpty, isPhone, isUrl } from "@nexdom/shared/utils";
6
7
  import { VHighlight } from "vuetify/labs/VHighlight";
7
8
  import { RouterLink } from "vue-router";
@@ -727,6 +728,35 @@ var navigation_menu_default = /* @__PURE__ */ defineComponent({
727
728
  }
728
729
  });
729
730
  //#endregion
731
+ //#region src/components/footer/footer.vue
732
+ var footer_default = /* @__PURE__ */ defineComponent({
733
+ inheritAttrs: false,
734
+ __name: "footer",
735
+ props: {
736
+ description: {
737
+ type: String,
738
+ required: false
739
+ },
740
+ dataTestid: {
741
+ type: String,
742
+ required: false
743
+ }
744
+ },
745
+ setup(__props) {
746
+ const props = __props;
747
+ return (_ctx, _cache) => {
748
+ return openBlock(), createBlock(unref(VFooter), {
749
+ "data-testid": props.dataTestid,
750
+ class: "justify-center text-center",
751
+ app: ""
752
+ }, {
753
+ default: withCtx(() => [createTextVNode(toDisplayString(props.description), 1)]),
754
+ _: 1
755
+ }, 8, ["data-testid"]);
756
+ };
757
+ }
758
+ });
759
+ //#endregion
730
760
  //#region src/composables/dimensions/dimensions.ts
731
761
  /**
732
762
  * Vuetify's utility class that stretches a component to the whole width of its parent, for
@@ -1182,6 +1212,10 @@ var main_default = /* @__PURE__ */ defineComponent({
1182
1212
  type: Object,
1183
1213
  required: false
1184
1214
  },
1215
+ footer: {
1216
+ type: Object,
1217
+ required: false
1218
+ },
1185
1219
  loading: {
1186
1220
  type: Boolean,
1187
1221
  required: false
@@ -1228,7 +1262,8 @@ var main_default = /* @__PURE__ */ defineComponent({
1228
1262
  _: 3
1229
1263
  })]),
1230
1264
  _: 3
1231
- })
1265
+ }),
1266
+ props.footer?.description ? (openBlock(), createBlock(footer_default, normalizeProps(mergeProps({ key: 2 }, props.footer)), null, 16)) : createCommentVNode("v-if", true)
1232
1267
  ]),
1233
1268
  _: 3
1234
1269
  }, 8, ["data-testid"]);
@@ -1799,6 +1834,228 @@ var date_time_field_default = /* @__PURE__ */ defineComponent({
1799
1834
  }
1800
1835
  });
1801
1836
  //#endregion
1837
+ //#region src/composables/inputs/mask-field.ts
1838
+ /**
1839
+ * Masks of the presets. Our preset names always map to these masks, never to
1840
+ * Vuetify's own presets (e.g. its American `phone`).
1841
+ */
1842
+ const maskFieldPresets = {
1843
+ cpf: "###.###.###-##",
1844
+ cnpj: "##.###.###/####-##",
1845
+ cep: "#####-###",
1846
+ phone: "(##) #####-####",
1847
+ date: "##/##/####"
1848
+ };
1849
+ /**
1850
+ * Returns the mask of a preset, or the given mask itself when it's a custom
1851
+ * one.
1852
+ *
1853
+ * It takes any string, as the `mask` prop may get one through a cast or from
1854
+ * JavaScript: a string that isn't a preset is taken as the mask.
1855
+ */
1856
+ function resolveMask(mask) {
1857
+ return isMaskFieldPreset(mask) ? maskFieldPresets[mask] : mask;
1858
+ }
1859
+ /**
1860
+ * Returns a mask as Vuetify reads it. `#` is our only token, but Vuetify always
1861
+ * adds its own tokens (`A`, `a`, `N`, `n` and `X`) and its escape (`\`), so
1862
+ * these characters are escaped to stay literals.
1863
+ */
1864
+ function toVuetifyMask(mask) {
1865
+ return mask.replaceAll(/[AaNnX\\]/g, String.raw`\$&`);
1866
+ }
1867
+ /**
1868
+ * Returns the default placeholder of a mask: the mask with `0` in place of each
1869
+ * `#`, keeping its literals (e.g. `000.000.000-00` for `cpf`).
1870
+ */
1871
+ function getMaskPlaceholder(mask) {
1872
+ return mask.replaceAll("#", "0");
1873
+ }
1874
+ function isMaskFieldPreset(mask) {
1875
+ return Object.hasOwn(maskFieldPresets, mask);
1876
+ }
1877
+ /**
1878
+ * Keeps the input masked while the user edits it, emitting only the digits
1879
+ * (Vuetify's `unmask`).
1880
+ *
1881
+ * A `v-model` out of the mask's format (masked, or with characters or length
1882
+ * the mask doesn't accept) is displayed normalized, without being emitted, and
1883
+ * validated as it is, so a value that doesn't fit the mask fails validation.
1884
+ */
1885
+ function useMaskField(props, model) {
1886
+ const mask = computed(() => resolveMask(props.mask));
1887
+ const digitCount = computed(() => mask.value.split("#").length - 1);
1888
+ const vuetifyMask = useMask({ get mask() {
1889
+ return {
1890
+ mask: toVuetifyMask(mask.value),
1891
+ tokens: {}
1892
+ };
1893
+ } });
1894
+ const displayValue = computed(() => vuetifyMask.mask(unmask(model.value)));
1895
+ const placeholder = computed(() => props.placeholder ?? getMaskPlaceholder(mask.value));
1896
+ const defaultRules = useRules(props);
1897
+ const rules = computed(() => [
1898
+ ...defaultRules.value,
1899
+ (value) => !value || !vuetifyMask.isValid(value) || isComplete(value) || "Valor incompleto",
1900
+ (value) => !value || vuetifyMask.isValid(value) || "Valor inválido"
1901
+ ]);
1902
+ function unmask(text) {
1903
+ return vuetifyMask.unmask(text) ?? "";
1904
+ }
1905
+ function isComplete(value) {
1906
+ return unmask(vuetifyMask.mask(value)).length === digitCount.value;
1907
+ }
1908
+ /**
1909
+ * Returns the position in a masked text right after the given number of
1910
+ * digits, skipping the literals after it unless the user deleted backwards
1911
+ * (as Vuetify's mask input does).
1912
+ */
1913
+ function findCaret(masked, valueLength, deletedBackwards) {
1914
+ let caret = 0;
1915
+ let found = 0;
1916
+ while (found < valueLength) {
1917
+ if (!vuetifyMask.isDelimiter(masked, caret)) found++;
1918
+ caret++;
1919
+ }
1920
+ if (!deletedBackwards) while (vuetifyMask.isDelimiter(masked, caret)) caret++;
1921
+ return caret;
1922
+ }
1923
+ function update(input, deletedBackwards) {
1924
+ const caret = input.selectionStart ?? input.value.length;
1925
+ const masked = vuetifyMask.mask(unmask(input.value));
1926
+ const newCaret = findCaret(masked, unmask(vuetifyMask.mask(unmask(input.value.slice(0, caret)))).length, deletedBackwards);
1927
+ const value = unmask(masked);
1928
+ input.value = masked;
1929
+ input.setSelectionRange(newCaret, newCaret);
1930
+ if (value !== unmask(displayValue.value)) model.value = value;
1931
+ }
1932
+ function onInput(event) {
1933
+ if (!event.isComposing) update(event.target, event.inputType.endsWith("Backward"));
1934
+ }
1935
+ function onCompositionEnd(event) {
1936
+ update(event.target, false);
1937
+ }
1938
+ return {
1939
+ displayValue,
1940
+ placeholder,
1941
+ rules,
1942
+ onInput,
1943
+ onCompositionEnd
1944
+ };
1945
+ }
1946
+ //#endregion
1947
+ //#region src/components/inputs/mask-field/mask-field.vue
1948
+ var mask_field_default = /* @__PURE__ */ defineComponent({
1949
+ inheritAttrs: false,
1950
+ __name: "mask-field",
1951
+ props: /*@__PURE__*/ mergeModels({
1952
+ variant: {
1953
+ type: String,
1954
+ required: false,
1955
+ default: "primary"
1956
+ },
1957
+ mask: {
1958
+ type: null,
1959
+ required: true
1960
+ },
1961
+ disabled: {
1962
+ type: Boolean,
1963
+ required: false
1964
+ },
1965
+ loading: {
1966
+ type: Boolean,
1967
+ required: false
1968
+ },
1969
+ clearable: {
1970
+ type: Boolean,
1971
+ required: false
1972
+ },
1973
+ readonly: {
1974
+ type: Boolean,
1975
+ required: false
1976
+ },
1977
+ required: {
1978
+ type: Boolean,
1979
+ required: false
1980
+ },
1981
+ label: {
1982
+ type: String,
1983
+ required: false
1984
+ },
1985
+ placeholder: {
1986
+ type: String,
1987
+ required: false
1988
+ },
1989
+ hint: {
1990
+ type: String,
1991
+ required: false
1992
+ },
1993
+ dataTestid: {
1994
+ type: String,
1995
+ required: false
1996
+ }
1997
+ }, {
1998
+ "modelValue": {
1999
+ type: String,
2000
+ default: ""
2001
+ },
2002
+ "modelModifiers": {}
2003
+ }),
2004
+ emits: ["update:modelValue"],
2005
+ setup(__props) {
2006
+ const modelValue = useModel(__props, "modelValue");
2007
+ const props = __props;
2008
+ const vuetifyVariant = useTextFieldVariant(() => props.variant);
2009
+ const { displayValue, placeholder, rules, onInput, onCompositionEnd } = useMaskField(props, modelValue);
2010
+ function keepFieldControlled() {}
2011
+ function clear() {
2012
+ modelValue.value = "";
2013
+ }
2014
+ return (_ctx, _cache) => {
2015
+ return openBlock(), createBlock(unref(VTextField), {
2016
+ "model-value": unref(displayValue),
2017
+ "validation-value": modelValue.value,
2018
+ variant: unref(vuetifyVariant),
2019
+ rules: unref(rules),
2020
+ "data-testid": props.dataTestid,
2021
+ disabled: props.disabled,
2022
+ loading: props.loading,
2023
+ "aria-busy": props.loading || void 0,
2024
+ readonly: props.readonly,
2025
+ label: props.label,
2026
+ placeholder: unref(placeholder),
2027
+ hint: props.hint,
2028
+ clearable: props.clearable,
2029
+ type: "text",
2030
+ inputmode: "numeric",
2031
+ "onUpdate:modelValue": keepFieldControlled,
2032
+ onInput: unref(onInput),
2033
+ onCompositionend: unref(onCompositionEnd),
2034
+ "onClick:clear": clear
2035
+ }, {
2036
+ loader: withCtx((loader) => [createVNode(field_loader_default, normalizeProps(guardReactiveProps(loader)), null, 16)]),
2037
+ _: 1
2038
+ }, 8, [
2039
+ "model-value",
2040
+ "validation-value",
2041
+ "variant",
2042
+ "rules",
2043
+ "data-testid",
2044
+ "disabled",
2045
+ "loading",
2046
+ "aria-busy",
2047
+ "readonly",
2048
+ "label",
2049
+ "placeholder",
2050
+ "hint",
2051
+ "clearable",
2052
+ "onInput",
2053
+ "onCompositionend"
2054
+ ]);
2055
+ };
2056
+ }
2057
+ });
2058
+ //#endregion
1802
2059
  //#region src/composables/alignment/alignment.ts
1803
2060
  const alignXToClass = {
1804
2061
  start: "justify-start",
@@ -2645,4 +2902,4 @@ var data_set_item_default = /* @__PURE__ */ defineComponent({
2645
2902
  }
2646
2903
  });
2647
2904
  //#endregion
2648
- export { autocomplete_field_default as UAutocompleteField, button_default as UButton, checkbox_default as UCheckbox, column_default as UColumn, container_default as UContainer, data_set_default as UDataSet, data_set_item_default as UDataSetItem, date_time_field_default as UDateTimeField, details_default as UDetails, dialog_default as UDialog, form_default as UForm, img_default as UImg, link_default as ULink, main_default as UMain, row_default as URow, section_default as USection, section_content_default as USectionContent, table_default as UTable, text_field_default as UTextField };
2905
+ export { autocomplete_field_default as UAutocompleteField, button_default as UButton, checkbox_default as UCheckbox, column_default as UColumn, container_default as UContainer, data_set_default as UDataSet, data_set_item_default as UDataSetItem, date_time_field_default as UDateTimeField, details_default as UDetails, dialog_default as UDialog, form_default as UForm, img_default as UImg, link_default as ULink, main_default as UMain, mask_field_default as UMaskField, row_default as URow, section_default as USection, section_content_default as USectionContent, table_default as UTable, text_field_default as UTextField };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexdom/uimed-vue",
3
- "version": "2.0.0-beta.37",
3
+ "version": "2.0.0-beta.39",
4
4
  "description": "A ui framework for NEXDOM applications.",
5
5
  "keywords": [
6
6
  "lib",