@nexdom/uimed-vue 2.0.0-beta.34 → 2.0.0-beta.36

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.
@@ -245,6 +245,10 @@ type TextFieldProps = {
245
245
  /**
246
246
  * Applies a distinct behavior to the field.
247
247
  * One of `text`, `phone`, `email`, `url`, `password` or `search`.
248
+ *
249
+ * With `password`, the field hides its value and shows a "Mostrar senha"
250
+ * button that toggles between showing and hiding it. The value hides again
251
+ * when the button is pressed again or the type changes.
248
252
  * @default "text"
249
253
  */
250
254
  type?: TextFieldType;
@@ -433,8 +437,8 @@ declare const __VLS_export$14: import("vue", { with: { "resolution-mode": "impor
433
437
  "onUpdate:modelValue"?: ((value: string) => any) | undefined;
434
438
  }>, {
435
439
  variant: TextFieldVariant;
436
- clearable: boolean;
437
440
  type: TextFieldType;
441
+ clearable: boolean;
438
442
  }, {}, {}, {}, string, import("vue", { with: { "resolution-mode": "import" } }).ComponentProvideOptions, false, {}, any>;
439
443
  //#endregion
440
444
  //#region src/components/inputs/checkbox/types.d.ts
@@ -1,8 +1,9 @@
1
1
  import { a as messages, n as owners$1, r as requests, s as useVuetifyColor } from "./use-dialog-Ck2_ZW7T.js";
2
- import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createTextVNode, createVNode, defineComponent, guardReactiveProps, inject, isRef, mergeModels, mergeProps, nextTick, normalizeClass, normalizeProps, onMounted, onScopeDispose, onUnmounted, openBlock, provide, ref, renderList, renderSlot, resolveDynamicComponent, shallowRef, toDisplayString, toValue, unref, useId, useModel, useSlots, useTemplateRef, watch, withCtx, withKeys, withModifiers } from "vue";
2
+ 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
3
  import { pt } from "vuetify/locale";
4
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
5
  import { formatDateTime, isEmail, isEmpty, isPhone, isUrl } from "@nexdom/shared/utils";
6
+ import { VHighlight } from "vuetify/labs/VHighlight";
6
7
  //#region src/composables/navigation/use-route-props.ts
7
8
  function useRouteProps(route) {
8
9
  return computed(() => routeToProps(route));
@@ -401,12 +402,39 @@ const textFieldTypeToVuetifyRule = {
401
402
  email,
402
403
  url
403
404
  };
404
- function useTextFieldType(type) {
405
+ /**
406
+ * Maps the field type to the input type, showing as plain text a password
407
+ * the user chose to make visible.
408
+ */
409
+ function useTextFieldType(type, isPasswordVisible) {
405
410
  return computed(() => {
406
411
  const typeValue = toValue(type);
412
+ if (typeValue === "password" && toValue(isPasswordVisible)) return "text";
407
413
  return textFieldTypeToVuetifyType[typeValue];
408
414
  });
409
415
  }
416
+ /**
417
+ * Controls the button that shows or hides a password field's value. The
418
+ * password starts hidden and hides again whenever the type stops being
419
+ * `password`.
420
+ */
421
+ function useTextFieldPasswordToggle(type) {
422
+ const isPasswordField = computed(() => toValue(type) === "password");
423
+ const isPasswordVisible = ref(false);
424
+ const icon = computed(() => isPasswordVisible.value ? "mdi-eye-off" : "mdi-eye");
425
+ watch(isPasswordField, () => {
426
+ isPasswordVisible.value = false;
427
+ });
428
+ function toggle() {
429
+ isPasswordVisible.value = !isPasswordVisible.value;
430
+ }
431
+ return {
432
+ isPasswordField,
433
+ isPasswordVisible: readonly(isPasswordVisible),
434
+ icon,
435
+ toggle
436
+ };
437
+ }
410
438
  function useTextFieldRules(props) {
411
439
  const defaultRules = useRules(props);
412
440
  return computed(() => {
@@ -512,7 +540,8 @@ var text_field_default = /* @__PURE__ */ defineComponent({
512
540
  const modelValue = useModel(__props, "modelValue");
513
541
  const props = __props;
514
542
  const vuetifyVariant = useTextFieldVariant(() => props.variant);
515
- const vuetifyType = useTextFieldType(() => props.type);
543
+ const { isPasswordField, isPasswordVisible, icon: passwordToggleIcon, toggle: togglePassword } = useTextFieldPasswordToggle(() => props.type);
544
+ const vuetifyType = useTextFieldType(() => props.type, isPasswordVisible);
516
545
  const rules = useTextFieldRules(props);
517
546
  const isSearchField = computed(() => props.type === "search");
518
547
  const computedClearable = computed(() => props.clearable ?? isSearchField.value);
@@ -538,10 +567,27 @@ var text_field_default = /* @__PURE__ */ defineComponent({
538
567
  hint: props.hint,
539
568
  clearable: computedClearable.value,
540
569
  "onClick:clear": clear
541
- }, {
570
+ }, createSlots({
542
571
  loader: withCtx((loader) => [createVNode(field_loader_default, normalizeProps(guardReactiveProps(loader)), null, 16)]),
543
- _: 1
544
- }, 8, [
572
+ _: 2
573
+ }, [unref(isPasswordField) ? {
574
+ name: "append-inner",
575
+ fn: withCtx(() => [createVNode(unref(VBtn), {
576
+ icon: unref(passwordToggleIcon),
577
+ "aria-label": "Mostrar senha",
578
+ "aria-pressed": unref(isPasswordVisible),
579
+ disabled: props.disabled,
580
+ size: "small",
581
+ variant: "text",
582
+ onClick: unref(togglePassword)
583
+ }, null, 8, [
584
+ "icon",
585
+ "aria-pressed",
586
+ "disabled",
587
+ "onClick"
588
+ ])]),
589
+ key: "0"
590
+ } : void 0]), 1032, [
545
591
  "modelValue",
546
592
  "variant",
547
593
  "type",
@@ -1298,6 +1344,8 @@ var autocomplete_field_default = /* @__PURE__ */ defineComponent({
1298
1344
  multiple: isMultiple.value
1299
1345
  }));
1300
1346
  const vuetifyComponent = computed(() => props.strict ? VAutocomplete : VCombobox);
1347
+ const search = ref("");
1348
+ const maskClass = computed(() => props.strict ? "v-autocomplete__mask" : "v-combobox__mask");
1301
1349
  const normalizedItems = computed(() => {
1302
1350
  return props.items.map((item) => {
1303
1351
  if (typeof item === "string") return {
@@ -1311,6 +1359,8 @@ var autocomplete_field_default = /* @__PURE__ */ defineComponent({
1311
1359
  return openBlock(), createBlock(resolveDynamicComponent(vuetifyComponent.value), {
1312
1360
  modelValue: modelValue.value,
1313
1361
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => modelValue.value = $event),
1362
+ search: search.value,
1363
+ "onUpdate:search": _cache[1] || (_cache[1] = ($event) => search.value = $event),
1314
1364
  variant: unref(vuetifyVariant),
1315
1365
  items: normalizedItems.value,
1316
1366
  "data-testid": props.dataTestid,
@@ -1327,11 +1377,35 @@ var autocomplete_field_default = /* @__PURE__ */ defineComponent({
1327
1377
  rules: unref(rules),
1328
1378
  "menu-props": unref(autocompleteFieldMenuProps),
1329
1379
  chips: ""
1330
- }, {
1380
+ }, createSlots({
1331
1381
  loader: withCtx((loader) => [createVNode(field_loader_default, normalizeProps(guardReactiveProps(loader)), null, 16)]),
1332
- _: 1
1333
- }, 8, [
1382
+ _: 2
1383
+ }, [isMultiple.value ? {
1384
+ name: "item",
1385
+ fn: withCtx(({ props: itemProps }) => [createVNode(unref(VListItem), normalizeProps(guardReactiveProps(itemProps)), {
1386
+ prepend: withCtx(({ isSelected }) => [createVNode(unref(VCheckboxBtn), {
1387
+ "model-value": isSelected,
1388
+ ripple: false,
1389
+ inert: "",
1390
+ "aria-hidden": "true"
1391
+ }, null, 8, ["model-value"])]),
1392
+ title: withCtx(() => [createVNode(unref(VHighlight), {
1393
+ text: itemProps.title,
1394
+ query: search.value,
1395
+ "match-all": "",
1396
+ "ignore-case": "",
1397
+ "mark-class": maskClass.value
1398
+ }, null, 8, [
1399
+ "text",
1400
+ "query",
1401
+ "mark-class"
1402
+ ])]),
1403
+ _: 2
1404
+ }, 1040)]),
1405
+ key: "0"
1406
+ } : void 0]), 1064, [
1334
1407
  "modelValue",
1408
+ "search",
1335
1409
  "variant",
1336
1410
  "items",
1337
1411
  "data-testid",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexdom/uimed-vue",
3
- "version": "2.0.0-beta.34",
3
+ "version": "2.0.0-beta.36",
4
4
  "description": "A ui framework for NEXDOM applications.",
5
5
  "keywords": [
6
6
  "lib",