vueless 0.0.568 → 0.0.570

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.
Files changed (90) hide show
  1. package/package.json +1 -1
  2. package/types.ts +14 -0
  3. package/ui.container-accordion/UAccordion.vue +2 -2
  4. package/ui.container-accordion/types.ts +1 -0
  5. package/ui.container-modal/UModal.vue +15 -8
  6. package/ui.container-page/UPage.vue +10 -6
  7. package/ui.form-calendar/UCalendar.vue +14 -25
  8. package/ui.form-calendar/config.ts +3 -0
  9. package/ui.form-calendar/constants.ts +0 -2
  10. package/ui.form-calendar/useAttrs.ts +1 -1
  11. package/ui.form-calendar/utilCalendar.ts +16 -9
  12. package/ui.form-calendar/utilFormatting.ts +63 -11
  13. package/ui.form-checkbox/types.ts +7 -0
  14. package/ui.form-checkbox-group/UCheckboxGroup.vue +1 -1
  15. package/ui.form-checkbox-multi-state/UCheckboxMultiState.vue +4 -1
  16. package/ui.form-color-picker/UColorPicker.vue +67 -147
  17. package/ui.form-color-picker/storybook/Docs.mdx +2 -2
  18. package/ui.form-color-picker/storybook/{stories.js → stories.ts} +13 -5
  19. package/ui.form-color-picker/types.ts +64 -0
  20. package/ui.form-color-picker/useAttrs.ts +15 -0
  21. package/ui.form-date-picker/UDatePicker.vue +109 -43
  22. package/ui.form-date-picker/config.ts +5 -5
  23. package/ui.form-date-picker-range/useAttrs.ts +1 -1
  24. package/ui.form-date-picker-range/useLocale.ts +1 -1
  25. package/ui.form-input/UInput.vue +162 -301
  26. package/ui.form-input/{config.js → config.ts} +3 -0
  27. package/ui.form-input/storybook/Docs.mdx +2 -2
  28. package/ui.form-input/storybook/{stories.js → stories.ts} +14 -6
  29. package/ui.form-input/types.ts +103 -0
  30. package/ui.form-input/useAttrs.ts +31 -0
  31. package/ui.form-input-file/UInputFile.vue +188 -245
  32. package/ui.form-input-file/storybook/Docs.mdx +2 -2
  33. package/ui.form-input-file/storybook/{stories.js → stories.ts} +13 -5
  34. package/ui.form-input-file/types.ts +72 -0
  35. package/ui.form-input-file/useAttrs.ts +21 -0
  36. package/ui.form-input-file/{utilFileForm.js → utilFileForm.ts} +1 -1
  37. package/ui.form-input-money/UInputMoney.vue +76 -223
  38. package/ui.form-input-money/storybook/Docs.mdx +2 -2
  39. package/ui.form-input-money/storybook/{stories.js → stories.ts} +14 -6
  40. package/ui.form-input-money/types.ts +118 -0
  41. package/ui.form-input-money/useAttrs.ts +15 -0
  42. package/ui.form-input-money/{useFormatCurrency.js → useFormatCurrency.ts} +28 -17
  43. package/ui.form-input-money/utilFormat.ts +83 -0
  44. package/ui.form-input-number/UInputNumber.vue +69 -156
  45. package/ui.form-input-number/storybook/Docs.mdx +2 -2
  46. package/ui.form-input-number/storybook/{stories.js → stories.ts} +17 -9
  47. package/ui.form-input-number/types.ts +65 -0
  48. package/ui.form-input-number/useAttrs.ts +15 -0
  49. package/ui.form-input-rating/UInputRating.vue +70 -158
  50. package/ui.form-input-rating/storybook/Docs.mdx +2 -2
  51. package/ui.form-input-rating/storybook/{stories.js → stories.ts} +14 -6
  52. package/ui.form-input-rating/types.ts +67 -0
  53. package/ui.form-input-rating/useAttrs.ts +14 -0
  54. package/ui.form-input-search/UInputSearch.vue +97 -224
  55. package/ui.form-input-search/storybook/Docs.mdx +2 -2
  56. package/ui.form-input-search/storybook/{stories.js → stories.ts} +13 -5
  57. package/ui.form-input-search/types.ts +93 -0
  58. package/ui.form-input-search/useAttrs.ts +15 -0
  59. package/ui.form-radio/URadio.vue +1 -1
  60. package/ui.form-radio-group/URadioGroup.vue +1 -1
  61. package/ui.navigation-pagination/UPagination.vue +15 -15
  62. package/ui.navigation-pagination/types.ts +3 -0
  63. package/ui.navigation-progress/UProgress.vue +16 -2
  64. package/ui.navigation-progress/types.ts +2 -0
  65. package/ui.text-files/UFiles.vue +20 -16
  66. package/ui.text-files/types.ts +1 -1
  67. package/ui.text-notify/UNotify.vue +38 -48
  68. package/ui.text-notify/types.ts +24 -0
  69. package/web-types.json +229 -132
  70. package/ui.form-color-picker/useAttrs.js +0 -9
  71. package/ui.form-input/useAttrs.js +0 -15
  72. package/ui.form-input-file/useAttrs.js +0 -15
  73. package/ui.form-input-money/useAttrs.js +0 -9
  74. package/ui.form-input-money/utilFormat.js +0 -75
  75. package/ui.form-input-number/useAttrs.js +0 -9
  76. package/ui.form-input-rating/useAttrs.js +0 -8
  77. package/ui.form-input-search/useAttrs.js +0 -9
  78. /package/ui.form-color-picker/{config.js → config.ts} +0 -0
  79. /package/ui.form-color-picker/{constants.js → constants.ts} +0 -0
  80. /package/ui.form-input/{constants.js → constants.ts} +0 -0
  81. /package/ui.form-input-file/{config.js → config.ts} +0 -0
  82. /package/ui.form-input-file/{constants.js → constants.ts} +0 -0
  83. /package/ui.form-input-money/{config.js → config.ts} +0 -0
  84. /package/ui.form-input-money/{constants.js → constants.ts} +0 -0
  85. /package/ui.form-input-number/{config.js → config.ts} +0 -0
  86. /package/ui.form-input-number/{constants.js → constants.ts} +0 -0
  87. /package/ui.form-input-rating/{config.js → config.ts} +0 -0
  88. /package/ui.form-input-rating/{constants.js → constants.ts} +0 -0
  89. /package/ui.form-input-search/{config.js → config.ts} +0 -0
  90. /package/ui.form-input-search/{constants.js → constants.ts} +0 -0
@@ -1,56 +1,4 @@
1
- <template>
2
- <ULabel
3
- :label="label"
4
- :description="description"
5
- :disabled="disabled"
6
- :error="error"
7
- :size="size"
8
- align="topWithDesc"
9
- v-bind="colorPickerLabelAttrs"
10
- :data-test="dataTest"
11
- >
12
- <div v-bind="listAttrs">
13
- <div v-bind="unselectedAttrs">
14
- <URadio
15
- :id="elementId"
16
- :name="name"
17
- :size="size"
18
- color="gray"
19
- :checked="selectedItem === ''"
20
- :disabled="disabled"
21
- v-bind="unselectedColorPickerRadioAttrs"
22
- @update:model-value="onUpdateValue('')"
23
- />
24
-
25
- <label :for="elementId">
26
- <UIcon
27
- v-if="selectedItem === ''"
28
- internal
29
- :size="iconSize"
30
- color="gray"
31
- :name="config.defaults.unselectedIcon"
32
- v-bind="unselectedIconAttrs"
33
- />
34
- </label>
35
- </div>
36
-
37
- <URadio
38
- v-for="(color, index) in colorOptions"
39
- :key="index"
40
- :name="name"
41
- :size="size"
42
- :value="color"
43
- :color="color"
44
- :checked="selectedItem === color"
45
- :disabled="disabled"
46
- v-bind="colorPickerRadioAttrs"
47
- @update:model-value="onUpdateValue(color)"
48
- />
49
- </div>
50
- </ULabel>
51
- </template>
52
-
53
- <script setup>
1
+ <script setup lang="ts">
54
2
  import { computed, useId } from "vue";
55
3
 
56
4
  import UIcon from "../ui.image-icon/UIcon.vue";
@@ -58,101 +6,21 @@ import URadio from "../ui.form-radio/URadio.vue";
58
6
  import ULabel from "../ui.form-label/ULabel.vue";
59
7
  import { getDefault } from "../utils/ui.ts";
60
8
 
61
- import { UColorPicker } from "./constants.js";
62
- import defaultConfig from "./config.js";
63
- import useAttrs from "./useAttrs.js";
9
+ import { UColorPicker } from "./constants.ts";
10
+ import defaultConfig from "./config.ts";
11
+ import useAttrs from "./useAttrs.ts";
64
12
 
65
- defineOptions({ inheritAttrs: false });
13
+ import type { UColorPickerProps, IconSize } from "./types.ts";
66
14
 
67
- const props = defineProps({
68
- /**
69
- * Color picker selected value.
70
- */
71
- modelValue: {
72
- type: String,
73
- default: "",
74
- },
75
-
76
- /**
77
- * Color picker name.
78
- */
79
- name: {
80
- type: String,
81
- default: getDefault(defaultConfig, UColorPicker).name,
82
- },
83
-
84
- /**
85
- * Color picker label.
86
- */
87
- label: {
88
- type: String,
89
- default: "",
90
- },
91
-
92
- /**
93
- * Color picker description.
94
- */
95
- description: {
96
- type: String,
97
- default: "",
98
- },
99
-
100
- /**
101
- * Error message.
102
- */
103
- error: {
104
- type: String,
105
- default: "",
106
- },
107
-
108
- /**
109
- * Color picker size.
110
- * @values sm, md, lg
111
- */
112
- size: {
113
- type: String,
114
- default: getDefault(defaultConfig, UColorPicker).size,
115
- },
116
-
117
- /**
118
- * Color picker color list.
119
- */
120
- colorOptions: {
121
- type: Array,
122
- default: () => getDefault(defaultConfig, UColorPicker).colorOptions,
123
- },
124
-
125
- /**
126
- * Set color picker disabled.
127
- */
128
- disabled: {
129
- type: Boolean,
130
- default: getDefault(defaultConfig, UColorPicker).disabled,
131
- },
132
-
133
- /**
134
- * Unique element id.
135
- */
136
- id: {
137
- type: String,
138
- default: "",
139
- },
140
-
141
- /**
142
- * Component config object.
143
- */
144
- config: {
145
- type: Object,
146
- default: () => ({}),
147
- },
15
+ defineOptions({ inheritAttrs: false });
148
16
 
149
- /**
150
- * Data-test attribute for automated testing.
151
- */
152
- dataTest: {
153
- type: String,
154
- default: "radio",
155
- },
17
+ const props = withDefaults(defineProps<UColorPickerProps>(), {
18
+ name: getDefault<UColorPickerProps>(defaultConfig, UColorPicker).name,
19
+ size: getDefault<UColorPickerProps>(defaultConfig, UColorPicker).size,
20
+ colorOptions: getDefault<UColorPickerProps>(defaultConfig, UColorPicker).colorOptions,
21
+ disabled: getDefault<UColorPickerProps>(defaultConfig, UColorPicker).disabled,
22
+ dataTest: "",
23
+ config: () => ({}),
156
24
  });
157
25
 
158
26
  const emit = defineEmits([
@@ -189,10 +57,62 @@ const iconSize = computed(() => {
189
57
  xl: "md",
190
58
  };
191
59
 
192
- return sizes[props.size];
60
+ return sizes[props.size] as IconSize;
193
61
  });
194
62
 
195
- function onUpdateValue(value) {
63
+ function onUpdateValue(value: string) {
196
64
  selectedItem.value = value;
197
65
  }
198
66
  </script>
67
+
68
+ <template>
69
+ <ULabel
70
+ :label="label"
71
+ :description="description"
72
+ :disabled="disabled"
73
+ :error="error"
74
+ :size="size"
75
+ align="topWithDesc"
76
+ v-bind="colorPickerLabelAttrs"
77
+ :data-test="dataTest"
78
+ >
79
+ <div v-bind="listAttrs">
80
+ <div v-bind="unselectedAttrs">
81
+ <URadio
82
+ :id="elementId"
83
+ :name="name"
84
+ :size="size"
85
+ color="gray"
86
+ :checked="selectedItem === ''"
87
+ :disabled="disabled"
88
+ v-bind="unselectedColorPickerRadioAttrs"
89
+ @update:model-value="onUpdateValue('')"
90
+ />
91
+
92
+ <label :for="elementId">
93
+ <UIcon
94
+ v-if="selectedItem === ''"
95
+ internal
96
+ :size="iconSize"
97
+ color="gray"
98
+ :name="config.defaults?.unselectedIcon"
99
+ v-bind="unselectedIconAttrs"
100
+ />
101
+ </label>
102
+ </div>
103
+
104
+ <URadio
105
+ v-for="(color, index) in colorOptions"
106
+ :key="index"
107
+ :name="name"
108
+ :size="size"
109
+ :value="color"
110
+ :color="color"
111
+ :checked="selectedItem === color"
112
+ :disabled="disabled"
113
+ v-bind="colorPickerRadioAttrs"
114
+ @update:model-value="onUpdateValue(color)"
115
+ />
116
+ </div>
117
+ </ULabel>
118
+ </template>
@@ -1,8 +1,8 @@
1
1
  import { Meta, Title, Subtitle, Description, Primary, Controls, Stories, Source } from "@storybook/blocks";
2
2
  import { getSource } from "../../utils/storybook.ts";
3
3
 
4
- import * as stories from "./stories.js";
5
- import defaultConfig from "../config.js?raw"
4
+ import * as stories from "./stories.ts";
5
+ import defaultConfig from "../config.ts?raw"
6
6
 
7
7
  <Meta of={stories} />
8
8
  <Title of={stories} />
@@ -8,6 +8,14 @@ import {
8
8
  import UColorPicker from "../../ui.form-color-picker/UColorPicker.vue";
9
9
  import UCol from "../../ui.container-col/UCol.vue";
10
10
 
11
+ import type { Meta, StoryFn } from "@storybook/vue3";
12
+ import type { UColorPickerProps } from "../types.ts";
13
+
14
+ interface UColorPickerArgs extends UColorPickerProps {
15
+ slotTemplate?: string;
16
+ enum: "size";
17
+ }
18
+
11
19
  export default {
12
20
  id: "3210",
13
21
  title: "Form Inputs & Controls / Color Picker",
@@ -22,9 +30,9 @@ export default {
22
30
  parameters: {
23
31
  ...getDocsDescription(UColorPicker.__name),
24
32
  },
25
- };
33
+ } as Meta;
26
34
 
27
- const DefaultTemplate = (args) => ({
35
+ const DefaultTemplate: StoryFn<UColorPickerArgs> = (args: UColorPickerArgs) => ({
28
36
  components: { UColorPicker },
29
37
  setup() {
30
38
  const slots = getSlotNames(UColorPicker.__name);
@@ -33,17 +41,17 @@ const DefaultTemplate = (args) => ({
33
41
  },
34
42
  template: `
35
43
  <UColorPicker v-bind="args" v-model="args.modelValue">
36
- ${args.slotTemplate || getSlotsFragment()}
44
+ ${args.slotTemplate || getSlotsFragment("")}
37
45
  </UColorPicker>
38
46
  `,
39
47
  });
40
48
 
41
- const EnumVariantTemplate = (args, { argTypes }) => ({
49
+ const EnumVariantTemplate: StoryFn<UColorPickerArgs> = (args: UColorPickerArgs, { argTypes }) => ({
42
50
  components: { UCol, UColorPicker },
43
51
  setup() {
44
52
  return {
45
53
  args,
46
- options: argTypes[args.enum].options,
54
+ options: argTypes?.[args.enum]?.options,
47
55
  };
48
56
  },
49
57
  template: `
@@ -0,0 +1,64 @@
1
+ import defaultConfig from "./config.ts";
2
+
3
+ import type { BrandColors } from "../types.ts";
4
+
5
+ export type Config = Partial<typeof defaultConfig>;
6
+
7
+ export type IconSize = "3xs" | "2xs" | "xs" | "sm" | "md";
8
+
9
+ export interface UColorPickerProps {
10
+ /**
11
+ * Color picker selected value.
12
+ */
13
+ modelValue?: string;
14
+
15
+ /**
16
+ * Color picker name.
17
+ */
18
+ name?: string;
19
+
20
+ /**
21
+ * Color picker label.
22
+ */
23
+ label?: string;
24
+
25
+ /**
26
+ * Color picker description.
27
+ */
28
+ description?: string;
29
+
30
+ /**
31
+ * Error message.
32
+ */
33
+ error?: string;
34
+
35
+ /**
36
+ * Color picker size.
37
+ */
38
+ size?: "sm" | "md" | "lg";
39
+
40
+ /**
41
+ * Color picker color list.
42
+ */
43
+ colorOptions?: Array<BrandColors>;
44
+
45
+ /**
46
+ * Set color picker disabled.
47
+ */
48
+ disabled?: boolean;
49
+
50
+ /**
51
+ * Unique element id.
52
+ */
53
+ id?: string;
54
+
55
+ /**
56
+ * Component config object.
57
+ */
58
+ config?: Config;
59
+
60
+ /**
61
+ * Data-test attribute for automated testing.
62
+ */
63
+ dataTest?: string;
64
+ }
@@ -0,0 +1,15 @@
1
+ import useUI from "../composables/useUI.ts";
2
+
3
+ import defaultConfig from "./config.ts";
4
+
5
+ import type { UseAttrs } from "../types.ts";
6
+ import type { UColorPickerProps, Config } from "./types.ts";
7
+
8
+ export default function useAttrs(props: UColorPickerProps): UseAttrs<Config> {
9
+ const { config, getKeysAttrs } = useUI<Config>(defaultConfig, () => props.config);
10
+
11
+ return {
12
+ config,
13
+ ...getKeysAttrs(),
14
+ };
15
+ }
@@ -5,22 +5,25 @@ import { merge } from "lodash-es";
5
5
  import UIcon from "../ui.image-icon/UIcon.vue";
6
6
  import UInput from "../ui.form-input/UInput.vue";
7
7
  import UCalendar from "../ui.form-calendar/UCalendar.vue";
8
- import { View, STANDARD_USER_FORMAT } from "../ui.form-calendar/constants.js";
8
+ import { View, LocaleType, ARROW_KEYS, TOKEN_REG_EXP } from "../ui.form-calendar/constants.ts";
9
9
 
10
10
  import { getDefault } from "../utils/ui.ts";
11
11
 
12
- import { addDays, isSameDay } from "../ui.form-calendar/utilDate.js";
13
- import { parseDate } from "../ui.form-calendar/utilCalendar.ts";
12
+ import { getSortedLocale } from "../ui.form-calendar/utilDate.ts";
13
+ import { formatDate, parseDate } from "../ui.form-calendar/utilCalendar.ts";
14
14
 
15
15
  import useAttrs from "./useAttrs.js";
16
16
  import { useLocale } from "../composables/useLocale.ts";
17
17
  import { useAutoPosition } from "../composables/useAutoPosition.ts";
18
18
 
19
- import defaultConfig from "./config.js";
20
- import { UDatePicker } from "./constants.js";
19
+ import defaultConfig from "./config.ts";
20
+ import { UDatePicker } from "./constants.ts";
21
+
22
+ import { vClickOutside } from "../directives";
21
23
 
22
24
  import type { UDatePickerProps } from "./types.ts";
23
25
  import type { ComponentExposed } from "../types.ts";
26
+ import type { DateLocale } from "../ui.form-calendar/utilFormatting.ts";
24
27
 
25
28
  defineOptions({ inheritAttrs: false });
26
29
 
@@ -65,6 +68,7 @@ const userFormatDate = ref("");
65
68
  const formattedDate = ref("");
66
69
  const customView = ref(View.Day);
67
70
 
71
+ const datepickerInputRef = useTemplateRef<typeof UInput>("input");
68
72
  const wrapperRef = useTemplateRef<HTMLDivElement>("wrapper");
69
73
  const calendarRef = useTemplateRef<ComponentExposed<typeof UCalendar>>("calendar");
70
74
 
@@ -84,6 +88,25 @@ const localValue = computed({
84
88
 
85
89
  const currentLocale = computed(() => merge(defaultConfig.i18n, i18nGlobal, props.config.i18n));
86
90
 
91
+ const clickOutsideOptions = computed(() => ({ ignore: [datepickerInputRef.value?.inputRef] }));
92
+
93
+ const locale = computed(() => {
94
+ const { months, weekdays } = currentLocale.value;
95
+
96
+ // formatted locale
97
+ return {
98
+ ...currentLocale.value,
99
+ months: {
100
+ shorthand: getSortedLocale(months.shorthand, LocaleType.Month),
101
+ longhand: getSortedLocale(months.longhand, LocaleType.Month),
102
+ },
103
+ weekdays: {
104
+ shorthand: getSortedLocale(weekdays.shorthand, LocaleType.Day),
105
+ longhand: getSortedLocale(weekdays.longhand, LocaleType.Day),
106
+ },
107
+ } as DateLocale;
108
+ });
109
+
87
110
  const elementId = props.id || useId();
88
111
 
89
112
  const { config, datepickerInputAttrs, datepickerInputActiveAttrs, calendarAttrs, wrapperAttrs } =
@@ -98,8 +121,6 @@ function activate() {
98
121
  nextTick(() => {
99
122
  adjustPositionY();
100
123
  adjustPositionX();
101
-
102
- calendarRef.value?.wrapperRef?.focus();
103
124
  });
104
125
  }
105
126
 
@@ -110,53 +131,93 @@ function deactivate() {
110
131
  }
111
132
 
112
133
  function onUserFormatDateChange(value: string) {
113
- userFormatDate.value = formatUserDate(value) || "";
134
+ userFormatDate.value = value.trim();
114
135
  }
115
136
 
116
137
  function onSubmit() {
117
138
  deactivate();
118
139
  }
119
140
 
120
- function onBlur(event: FocusEvent) {
121
- const { relatedTarget } = event;
122
-
123
- if (!calendarRef?.value?.wrapperRef?.contains(relatedTarget as HTMLElement)) deactivate();
141
+ function onInput() {
142
+ nextTick(() => {
143
+ deactivate();
144
+ emit("input", localValue.value);
145
+ });
124
146
  }
125
147
 
126
- function formatUserDate(data: string) {
127
- if (props.userDateFormat !== STANDARD_USER_FORMAT || props.timepicker) return data;
128
-
129
- let prefix = "";
130
- const formattedDate = data.charAt(0).toUpperCase() + data.toLowerCase().slice(1);
131
- const formattedDateWithoutDay = formattedDate.split(",").slice(1).join("").trim();
132
-
133
- const today = new Date();
134
-
135
- const parsedLocalDate = parseDate(localValue.value, props.dateFormat, currentLocale.value);
136
- const isToday = parsedLocalDate && isSameDay(today, parsedLocalDate);
137
- const isYesterday = parsedLocalDate && isSameDay(addDays(today, -1), parsedLocalDate);
138
- const isTomorrow = parsedLocalDate && isSameDay(addDays(today, 1), parsedLocalDate);
139
-
140
- if (isToday) {
141
- prefix = currentLocale.value.today;
148
+ function onTextInput() {
149
+ if (datepickerInputRef.value?.inputRef) {
150
+ datepickerInputRef.value.inputRef.value = userFormatDate.value;
142
151
  }
152
+ }
143
153
 
144
- if (isYesterday) {
145
- prefix = currentLocale.value.yesterday;
154
+ function onPaste(event: ClipboardEvent) {
155
+ try {
156
+ const pasteContent = event.clipboardData ? event.clipboardData.getData("text/plain") : "";
157
+ const userFormat = props.timepicker ? props.userDateTimeFormat : props.userDateFormat;
158
+ const relativeTokensAmount = Number(userFormat.match(/(?<!\\)r/g)?.length);
159
+
160
+ // Amount of tokens used in format string without decimeters.
161
+ const tokensAmount = userFormat
162
+ .split("")
163
+ .filter((char) => Object.keys(TOKEN_REG_EXP).includes(char)).length;
164
+
165
+ // Amount of substring that satisfies format tokens.
166
+ let pastedTokensAmount = pasteContent
167
+ .replace(/[^a-zA-Z0-9]/g, " ")
168
+ .replace(/\s+/g, " ")
169
+ .trim()
170
+ .split(" ").length;
171
+
172
+ const isPastedRelativeDay = [
173
+ locale.value.tomorrow,
174
+ locale.value.today,
175
+ locale.value.tomorrow,
176
+ ].some((word) => {
177
+ return pasteContent.includes(word);
178
+ });
179
+
180
+ if (isPastedRelativeDay) {
181
+ pastedTokensAmount -= relativeTokensAmount;
182
+ }
183
+
184
+ if (pastedTokensAmount !== tokensAmount) return;
185
+
186
+ const parsedDate = parseDate(pasteContent, userFormat, locale.value);
187
+
188
+ if (parsedDate) {
189
+ localValue.value = (
190
+ props.dateFormat ? formatDate(parsedDate, props.dateFormat, locale.value) : parsedDate
191
+ ) as TModelValue;
192
+ }
193
+ } catch (error) {
194
+ // eslint-disable-next-line no-console
195
+ console.log(error);
146
196
  }
197
+ }
147
198
 
148
- if (isTomorrow) {
149
- prefix = currentLocale.value.tomorrow;
199
+ function onCopy(event: ClipboardEvent) {
200
+ const target = event.target as HTMLInputElement;
201
+
202
+ const cursorStart = target.selectionStart || 0;
203
+ const cursorEnd = target.selectionEnd || 0;
204
+
205
+ try {
206
+ if (cursorStart !== cursorEnd) {
207
+ navigator.clipboard.writeText(target.value.substring(cursorStart, cursorEnd));
208
+ } else {
209
+ navigator.clipboard.writeText(target.value);
210
+ }
211
+ } catch (error) {
212
+ // eslint-disable-next-line no-console
213
+ console.error(error);
150
214
  }
151
-
152
- return prefix ? `${prefix}, ${formattedDateWithoutDay}` : formattedDate;
153
215
  }
154
216
 
155
- function onInput() {
156
- nextTick(() => {
157
- calendarRef.value?.wrapperRef?.blur();
158
- emit("input", localValue.value);
159
- });
217
+ function onTextInputKeyDown(event: KeyboardEvent) {
218
+ if (ARROW_KEYS.includes(event.code)) {
219
+ calendarRef.value?.wrapperRef?.focus();
220
+ }
160
221
  }
161
222
 
162
223
  defineExpose({
@@ -184,20 +245,25 @@ defineExpose({
184
245
  <div v-bind="wrapperAttrs" ref="wrapper">
185
246
  <UInput
186
247
  :id="elementId"
187
- :key="String(isShownCalendar)"
188
- v-model="userFormatDate"
248
+ :key="String(localValue)"
249
+ ref="input"
250
+ :model-value="userFormatDate"
189
251
  :label-align="labelAlign"
190
252
  :label="label"
191
253
  :placeholder="placeholder"
192
254
  :error="error"
193
255
  :description="description"
194
- readonly
195
256
  :disabled="disabled"
196
257
  :size="size"
197
258
  :left-icon="leftIcon"
198
259
  :right-icon="rightIcon"
199
260
  v-bind="isShownCalendar ? datepickerInputActiveAttrs : datepickerInputAttrs"
261
+ @input="onTextInput"
200
262
  @focus="activate"
263
+ @paste="onPaste"
264
+ @copy="onCopy"
265
+ @keydown.esc="deactivate"
266
+ @keydown="onTextInputKeyDown"
201
267
  >
202
268
  <template #left>
203
269
  <!-- @slot Use it add something before the date. -->
@@ -236,6 +302,7 @@ defineExpose({
236
302
  ref="calendar"
237
303
  v-model="localValue"
238
304
  v-model:view="customView"
305
+ v-click-outside="[deactivate, clickOutsideOptions]"
239
306
  :tabindex="-1"
240
307
  :timepicker="timepicker"
241
308
  :date-format="dateFormat"
@@ -248,7 +315,6 @@ defineExpose({
248
315
  @keydown.esc="deactivate"
249
316
  @user-date-change="onUserFormatDateChange"
250
317
  @input="onInput"
251
- @blur="onBlur"
252
318
  @submit="onSubmit"
253
319
  />
254
320
  </Transition>
@@ -37,9 +37,9 @@ export default /*tw*/ {
37
37
  leaveToClass: "opacity-0 scale-95",
38
38
  },
39
39
  i18n: {
40
- today: "Today",
41
- yesterday: "Yesterday",
42
- tomorrow: "Tomorrow",
40
+ today: "Today,",
41
+ yesterday: "Yesterday,",
42
+ tomorrow: "Tomorrow,",
43
43
  weekdays: {
44
44
  shorthand: {
45
45
  sunday: "Sun",
@@ -117,8 +117,8 @@ export default /*tw*/ {
117
117
  okLabel: "Ok",
118
118
  },
119
119
  defaults: {
120
- userDateFormat: "j F, Y",
121
- userDateTimeFormat: "j F, Y - H:i:S",
120
+ userDateFormat: "r j F, Y",
121
+ userDateTimeFormat: "r j F, Y - H:i:S",
122
122
  size: "md",
123
123
  openDirectionX: "auto",
124
124
  openDirectionY: "auto",
@@ -3,7 +3,7 @@ import { merge } from "lodash-es";
3
3
 
4
4
  import useUI from "../composables/useUI.ts";
5
5
 
6
- import defaultConfig from "./config.js";
6
+ import defaultConfig from "./config.ts";
7
7
  import { Direction } from "../composables/useAutoPosition.ts";
8
8
 
9
9
  import type { Ref } from "vue";
@@ -4,7 +4,7 @@ import { useLocale as useGlobalLocale } from "../composables/useLocale.ts";
4
4
 
5
5
  import { getSortedLocale } from "../ui.form-calendar/utilDate.ts";
6
6
  import { LocaleType } from "../ui.form-calendar/constants.ts";
7
- import { UDatePickerRange } from "./constants.js";
7
+ import { UDatePickerRange } from "./constants.ts";
8
8
 
9
9
  import defaultConfig from "./config.ts";
10
10