@amirjalili1374/ui-kit 1.2.0 → 1.2.2

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 (141) hide show
  1. package/README.md +11 -11
  2. package/package.json +3 -3
  3. package/src/assets/fonts/A Massir Spray.ttf +0 -0
  4. package/src/assets/fonts/BYekan.ttf +0 -0
  5. package/src/assets/fonts/BYekan.woff +0 -0
  6. package/src/assets/fonts/BYekan.woff2 +0 -0
  7. package/src/assets/fonts/Dima Shekasteh 2 Free.ttf +0 -0
  8. package/src/assets/fonts/Dima Shekasteh Free Regular.ttf +0 -0
  9. package/src/assets/fonts/IRANSansWeb.ts +0 -1
  10. package/src/assets/fonts/IRANSansWeb.ttf +0 -0
  11. package/src/assets/fonts/IRANSansXBlack.ttf +0 -0
  12. package/src/assets/fonts/IRANSansXBold.ttf +0 -0
  13. package/src/assets/fonts/IRANSansXDemiBold.ttf +0 -0
  14. package/src/assets/fonts/IRANSansXExtraBold.ttf +0 -0
  15. package/src/assets/fonts/IRANSansXLight.ttf +0 -0
  16. package/src/assets/fonts/IRANSansXMedium.ttf +0 -0
  17. package/src/assets/fonts/IRANSansXRegular.ttf +0 -0
  18. package/src/assets/fonts/IRANSansXThin.ttf +0 -0
  19. package/src/assets/fonts/IRANSansXUltraLight.ttf +0 -0
  20. package/src/assets/fonts/IranNastaliq.ttf +0 -0
  21. package/src/assets/fonts/Vazir-Medium-FD.ttf +0 -0
  22. package/src/assets/fonts/Vazir-Medium-FD.woff +0 -0
  23. package/src/assets/fonts/Vazir-Medium-FD.woff2 +0 -0
  24. package/src/assets/fonts/Vazir-Regular-FD.eot +0 -0
  25. package/src/assets/fonts/kalamehBold.woff +0 -0
  26. package/src/assets/fonts/kalamehBold.woff2 +0 -0
  27. package/src/assets/fonts/kalamehHeavy.woff +0 -0
  28. package/src/assets/fonts/kalamehHeavy.woff2 +0 -0
  29. package/src/assets/fonts/kalamehLight.woff +0 -0
  30. package/src/assets/fonts/kalamehLight.woff2 +0 -0
  31. package/src/assets/fonts/kalamehRegular.woff +0 -0
  32. package/src/assets/fonts/kalamehRegular.woff2 +0 -0
  33. package/src/assets/images/auth/social-google.svg +0 -6
  34. package/src/assets/images/favicon.svg +0 -18
  35. package/src/assets/images/icons/icon-card.svg +0 -5
  36. package/src/assets/images/logos/logo.svg +0 -12
  37. package/src/assets/images/logos/logolight.svg +0 -12
  38. package/src/assets/images/maintenance/img-error-bg.svg +0 -34
  39. package/src/assets/images/maintenance/img-error-blue.svg +0 -43
  40. package/src/assets/images/maintenance/img-error-purple.svg +0 -42
  41. package/src/assets/images/maintenance/img-error-text.svg +0 -27
  42. package/src/assets/images/profile/profile-user-account-svgrepo-com.svg +0 -12
  43. package/src/assets/images/profile/user-round.svg +0 -15
  44. package/src/assets/images/template/template-01.ts +0 -1
  45. package/src/assets/images/vectors/colorized-bg.svg +0 -40
  46. package/src/assets/images/vectors/logo_stroke_1px.svg +0 -26
  47. package/src/assets/images/vectors/logo_stroke_2px.svg +0 -26
  48. package/src/assets/scss/components/_approval-sections.scss +0 -75
  49. package/src/assets/styles/fonts.scss +0 -77
  50. package/src/components/Loading.vue +0 -88
  51. package/src/components/common/AppStepper.vue +0 -139
  52. package/src/components/shared/BaseBreadcrumb.vue +0 -55
  53. package/src/components/shared/BaseIcon.vue +0 -27
  54. package/src/components/shared/ConfirmDialog.vue +0 -72
  55. package/src/components/shared/CustomAutocomplete.vue +0 -306
  56. package/src/components/shared/CustomDataTable.vue +0 -1859
  57. package/src/components/shared/DescriptionInput.vue +0 -204
  58. package/src/components/shared/DownloadButton.vue +0 -169
  59. package/src/components/shared/MoneyInput.vue +0 -105
  60. package/src/components/shared/PdfViewer.vue +0 -645
  61. package/src/components/shared/ShamsiDatePicker.vue +0 -444
  62. package/src/components/shared/UiChildCard.vue +0 -17
  63. package/src/components/shared/UiParentCard.vue +0 -21
  64. package/src/components/shared/VPriceTextField.vue +0 -136
  65. package/src/composables/useDataTable.ts +0 -152
  66. package/src/composables/usePermissions.ts +0 -90
  67. package/src/composables/useRouteGuard.ts +0 -36
  68. package/src/composables/useTableActions.ts +0 -207
  69. package/src/composables/useTableHeaders.ts +0 -172
  70. package/src/composables/useTableSelection.ts +0 -201
  71. package/src/constants/enums/approval.ts +0 -13
  72. package/src/constants/enums/booleanEnum.ts +0 -11
  73. package/src/constants/enums/contractType.ts +0 -11
  74. package/src/constants/enums/lcProductType.ts +0 -21
  75. package/src/constants/enums/repaymentType.ts +0 -11
  76. package/src/directives/v-digit-limit.ts +0 -15
  77. package/src/directives/v-permission.ts +0 -31
  78. package/src/features/index.ts +0 -48
  79. package/src/index.ts +0 -119
  80. package/src/plugins/key-clock.ts +0 -39
  81. package/src/plugins/mdi-icon.ts +0 -31
  82. package/src/plugins/vuetify.ts +0 -74
  83. package/src/scss/_override.scss +0 -72
  84. package/src/scss/_variables.scss +0 -124
  85. package/src/scss/components/_VButtons.scss +0 -23
  86. package/src/scss/components/_VCard.scss +0 -20
  87. package/src/scss/components/_VCustomDataTable.scss +0 -282
  88. package/src/scss/components/_VField.scss +0 -9
  89. package/src/scss/components/_VInput.scss +0 -17
  90. package/src/scss/components/_VNavigationDrawer.scss +0 -3
  91. package/src/scss/components/_VShadow.scss +0 -3
  92. package/src/scss/components/_VStepper.scss +0 -235
  93. package/src/scss/components/_VTabs.scss +0 -11
  94. package/src/scss/components/_VTextField.scss +0 -40
  95. package/src/scss/components/_approval.scss +0 -128
  96. package/src/scss/layout/_container.scss +0 -147
  97. package/src/scss/layout/_sidebar.scss +0 -138
  98. package/src/scss/layout/_topbar.scss +0 -39
  99. package/src/scss/pages/_dashboards.scss +0 -97
  100. package/src/scss/style.scss +0 -21
  101. package/src/services/apiService.ts +0 -59
  102. package/src/services/axiosInstance.ts +0 -14
  103. package/src/stores/customizer.ts +0 -55
  104. package/src/stores/permissions.ts +0 -237
  105. package/src/theme/darkThemes/DarkModernTheme.ts +0 -54
  106. package/src/theme/darkThemes/DarkOrangeTheme.ts +0 -53
  107. package/src/theme/darkThemes/DarkPurpleTheme.ts +0 -54
  108. package/src/theme/darkThemes/DarkRedTheme.ts +0 -54
  109. package/src/theme/darkThemes/DarkSilverTheme.ts +0 -53
  110. package/src/theme/darkThemes/DarkSteelTealGreen.ts +0 -53
  111. package/src/theme/darkThemes/DarkTealTheme.ts +0 -52
  112. package/src/theme/lightThemes/ModernTheme.ts +0 -55
  113. package/src/theme/lightThemes/OrangeTheme.ts +0 -54
  114. package/src/theme/lightThemes/PurpleTheme.ts +0 -54
  115. package/src/theme/lightThemes/RedTheme.ts +0 -55
  116. package/src/theme/lightThemes/SilverTheme.ts +0 -55
  117. package/src/theme/lightThemes/SteelTealGreen.ts +0 -54
  118. package/src/theme/lightThemes/TealTheme.ts +0 -54
  119. package/src/types/approval/approvalType.ts +0 -473
  120. package/src/types/cartable/cartableTypes.ts +0 -169
  121. package/src/types/componentTypes/DataTableType.ts +0 -14
  122. package/src/types/componentTypes/DataTableTypes.ts +0 -130
  123. package/src/types/enums/global.ts +0 -267
  124. package/src/types/jalaali-js.d.ts +0 -6
  125. package/src/types/models/Base.ts +0 -4
  126. package/src/types/models/env.d.ts +0 -10
  127. package/src/types/models/person.ts +0 -13
  128. package/src/types/models/userInfo.ts +0 -29
  129. package/src/types/preApproval/preApprovalTypes.ts +0 -67
  130. package/src/types/shims-tabler-icons.d.ts +0 -58
  131. package/src/types/themeTypes/ThemeType.ts +0 -47
  132. package/src/types/vue-apexcharts.d.ts +0 -1
  133. package/src/types/vue3-print-nb.d.ts +0 -1
  134. package/src/types/vue_tabler_icon.d.ts +0 -10
  135. package/src/utils/NationalCodeValidator.ts +0 -33
  136. package/src/utils/date-convertor.ts +0 -40
  137. package/src/utils/greetingUtils.ts +0 -97
  138. package/src/utils/helpers/fake-backend.ts +0 -68
  139. package/src/utils/helpers/fetch-wrapper.ts +0 -86
  140. package/src/utils/number-formatter.ts +0 -33
  141. package/src/validators/nationalCodeRule.ts +0 -6
@@ -1,444 +0,0 @@
1
- <template>
2
- <div class="shamsi-date-picker">
3
- <Vue3PersianDatetimePicker
4
- :label="label"
5
- v-model="selectedDate"
6
- :format="format"
7
- :display-format="displayFormat"
8
- :editable="false"
9
- :clearable="clearable"
10
- :disabled="disabled"
11
- :min="minDate"
12
- :max="maxDate"
13
- :placeholder="placeholder"
14
- :input-class="inputClass"
15
- :wrapper-class="wrapperClass"
16
- :range="isRangeMode"
17
- :color="color"
18
- @change="onDateChange"
19
- />
20
- </div>
21
- </template>
22
-
23
- <script setup lang="ts">
24
- import { computed } from 'vue';
25
-
26
- interface Props {
27
- modelValue?: string | [string, string] | null; // Single date or range
28
- label?: string;
29
- placeholder?: string;
30
- variant?: 'outlined' | 'filled' | 'plain' | 'underlined' | 'solo' | 'solo-inverted' | 'solo-filled';
31
- density?: 'default' | 'comfortable' | 'compact' | 'prominent';
32
- color?: string;
33
- disabled?: boolean;
34
- readonly?: boolean;
35
- clearable?: boolean;
36
- rules?: any[];
37
- hideDetails?: boolean | 'auto';
38
- prependInnerIcon?: string;
39
- appendInnerIcon?: string;
40
- format?: string;
41
- displayFormat?: string;
42
- minDate?: string;
43
- maxDate?: string;
44
- mode?: 'single' | 'range'; // Single date or range picker
45
- icon?: string; // Custom calendar icon
46
- }
47
-
48
- const props = withDefaults(defineProps<Props>(), {
49
- modelValue: '',
50
- label: 'تاریخ',
51
- placeholder: 'تاریخ را انتخاب کنید',
52
- variant: 'outlined',
53
- density: 'default',
54
- color: 'primary',
55
- disabled: false,
56
- readonly: false,
57
- clearable: true,
58
- rules: () => [],
59
- hideDetails: 'auto',
60
- prependInnerIcon: '',
61
- appendInnerIcon: '',
62
- format: 'YYYY-MM-DD',
63
- displayFormat: 'jYYYY/jMM/jDD',
64
- minDate: '',
65
- maxDate: '',
66
- mode: 'single',
67
- icon: ''
68
- });
69
-
70
- const emit = defineEmits<{
71
- 'update:modelValue': [value: string | [string, string] | null];
72
- }>();
73
-
74
- const selectedDate = computed({
75
- get: () => {
76
- // Pass Gregorian date directly to the library, let it handle Shamsi display
77
- if (props.mode === 'range' && Array.isArray(props.modelValue)) {
78
- return props.modelValue;
79
- } else if (typeof props.modelValue === 'string' && props.modelValue) {
80
- console.log('Passing Gregorian date to picker:', props.modelValue);
81
- // Convert ISO string to local date to avoid timezone issues
82
- if (props.modelValue.includes('T')) {
83
- const date = new Date(props.modelValue);
84
- // Format as YYYY-MM-DD to avoid timezone confusion
85
- const localDate = date.getFullYear() + '-' +
86
- String(date.getMonth() + 1).padStart(2, '0') + '-' +
87
- String(date.getDate()).padStart(2, '0');
88
- console.log('Converted to local date:', localDate);
89
- return localDate;
90
- }
91
- // Otherwise, create a proper date string that the picker can handle
92
- return props.modelValue + 'T00:00:00.000Z';
93
- }
94
- return props.modelValue;
95
- },
96
- set: (value) => {
97
- console.log('selectedDate setter called with:', value);
98
- emit('update:modelValue', value);
99
- }
100
- });
101
-
102
- const onDateChange = (date: any) => {
103
- console.log('Date changed:', date);
104
-
105
- if (props.mode === 'range') {
106
- // Handle range mode
107
- if (Array.isArray(date) && date.length === 2) {
108
- const [startDate, endDate] = date;
109
- const gregorianStart = startDate && startDate._isAMomentObject ?
110
- startDate.toISOString() : startDate;
111
- const gregorianEnd = endDate && endDate._isAMomentObject ?
112
- endDate.toISOString() : endDate;
113
-
114
- console.log('Range - Start:', gregorianStart, 'End:', gregorianEnd);
115
- emit('update:modelValue', [gregorianStart, gregorianEnd]);
116
- } else {
117
- emit('update:modelValue', null);
118
- }
119
- } else {
120
- // Handle single date mode
121
- if (date && date._isAMomentObject && date.isValid()) {
122
- // Use Moment's toISOString method to get full ISO format with timezone
123
- const gregorianISO = date.toISOString();
124
- console.log('Single date - Gregorian for server:', gregorianISO);
125
- emit('update:modelValue', gregorianISO);
126
- } else if (typeof date === 'string') {
127
- // If it's a string, convert to ISO format
128
- const dateObj = new Date(date);
129
- const gregorianISO = dateObj.toISOString();
130
- console.log('String date converted to ISO:', gregorianISO);
131
- emit('update:modelValue', gregorianISO);
132
- } else {
133
- emit('update:modelValue', '');
134
- }
135
- }
136
- };
137
-
138
- // CSS classes for Vuetify-like styling
139
- const inputClass = computed(() => {
140
- const classes = ['v-text-field', 'v-input', 'v-input--density-comfortable'];
141
- if (props.variant === 'outlined') {
142
- classes.push('v-text-field--variant-outlined');
143
- }
144
- return classes.join(' ');
145
- });
146
-
147
- const wrapperClass = computed(() => {
148
- return 'v-field v-field--variant-outlined v-field--density-comfortable';
149
- });
150
-
151
- // Check if range mode is enabled
152
- const isRangeMode = computed(() => props.mode === 'range');
153
- </script>
154
-
155
- <style scoped>
156
- .shamsi-date-picker {
157
- position: relative;
158
- }
159
-
160
- /* Style the Persian date picker input to look like Vuetify */
161
- .shamsi-date-picker :deep(.vpd-input-group) {
162
- border: 1px solid rgb(var(--v-theme-borderLight));
163
- border-radius: 10px;
164
- transition: border-color 0.2s ease, box-shadow 0.2s ease;
165
- background: rgb(var(--v-theme-surface));
166
- position: relative;
167
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
168
- }
169
-
170
- .shamsi-date-picker :deep(.vpd-input-group:hover) {
171
- border-color: rgb(var(--v-theme-secondary));
172
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.08);
173
- }
174
-
175
- .shamsi-date-picker :deep(.vpd-input-group:focus-within) {
176
- border-color: rgb(var(--v-theme-primary));
177
- box-shadow: 0 0 0 2px rgba(var(--v-theme-primary), 0.1);
178
- }
179
-
180
- .shamsi-date-picker :deep(.vpd-input-group input) {
181
- padding: 12px 16px;
182
- font-size: 16px;
183
- border: none;
184
- outline: none;
185
- background: transparent;
186
- width: 100%;
187
- box-sizing: border-box;
188
- color: rgb(var(--v-theme-onSurface));
189
- }
190
-
191
- .shamsi-date-picker :deep(.vpd-input-group input::placeholder) {
192
- color: rgb(var(--v-theme-onSurfaceVariant));
193
- opacity: 0.7;
194
- }
195
-
196
- .shamsi-date-picker :deep(.vpd-icon-btn) {
197
- padding: 8px;
198
- border-radius: 6px;
199
- margin: 4px;
200
- cursor: pointer;
201
- background: linear-gradient(135deg, rgb(var(--v-theme-primary)) 0%, rgb(var(--v-theme-secondary)) 100%) !important;
202
- color: white !important;
203
- transition: all 0.2s ease;
204
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
205
- }
206
-
207
- .shamsi-date-picker :deep(.vpd-icon-btn:hover) {
208
- transform: translateY(-1px);
209
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
210
- }
211
-
212
- .shamsi-date-picker :deep(.vpd-icon-btn:active) {
213
- transform: translateY(0);
214
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
215
- }
216
-
217
- /* Custom icon styling */
218
- .shamsi-date-picker :deep(.vpd-icon-btn i) {
219
- font-size: 16px;
220
- filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.1));
221
- }
222
-
223
- /* Range mode styling */
224
- .shamsi-date-picker :deep(.vpd-range) {
225
- background: linear-gradient(135deg, rgb(var(--v-theme-primary)) 0%, rgb(var(--v-theme-secondary)) 100%) !important;
226
- opacity: 0.2;
227
- }
228
-
229
- /* Calendar popup styling */
230
- .shamsi-date-picker :deep(.vpd-picker) {
231
- background: rgb(var(--v-theme-surface));
232
- border: 1px solid rgb(var(--v-theme-borderLight));
233
- border-radius: 12px;
234
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
235
- }
236
-
237
- /* Calendar header */
238
- .shamsi-date-picker :deep(.vpd-header) {
239
- background: linear-gradient(135deg, rgb(var(--v-theme-primary)) 0%, rgb(var(--v-theme-secondary)) 100%);
240
- color: white;
241
- }
242
-
243
- /* Calendar navigation buttons */
244
- .shamsi-date-picker :deep(.vpd-nav-btn) {
245
- background: rgba(255, 255, 255, 0.2) !important;
246
- color: white !important;
247
- border-radius: 6px;
248
- transition: all 0.2s ease;
249
- }
250
-
251
- .shamsi-date-picker :deep(.vpd-nav-btn:hover) {
252
- background: rgba(255, 255, 255, 0.3) !important;
253
- transform: scale(1.05);
254
- }
255
-
256
- /* Calendar days */
257
- .shamsi-date-picker :deep(.vpd-day) {
258
- color: rgb(var(--v-theme-onSurface));
259
- border-radius: 6px;
260
- transition: all 0.2s ease;
261
- font-weight: 500;
262
- }
263
-
264
- /* Ensure proper contrast for calendar days */
265
- .shamsi-date-picker :deep(.vpd-day) {
266
- color: rgb(var(--v-theme-onSurface)) !important;
267
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
268
- }
269
-
270
- /* Force better visibility in dark mode */
271
- .shamsi-date-picker :deep(.vpd-day) {
272
- color: rgb(var(--v-theme-secondary)) !important;
273
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
274
- }
275
-
276
- .shamsi-date-picker :deep(.vpd-day:hover) {
277
- background: rgb(var(--v-theme-primaryContainer)) !important;
278
- color: rgb(var(--v-theme-onPrimaryContainer)) !important;
279
- }
280
-
281
- .shamsi-date-picker :deep(.vpd-day.vpd-selected) {
282
- background: rgb(var(--v-theme-primary)) !important;
283
- color: white !important;
284
- box-shadow: 0 2px 8px rgba(var(--v-theme-primary), 0.3);
285
- }
286
-
287
- .shamsi-date-picker :deep(.vpd-day.vpd-today) {
288
- border: 2px solid rgb(var(--v-theme-primary));
289
- font-weight: bold;
290
- }
291
-
292
- /* Month/Year selector */
293
- .shamsi-date-picker :deep(.vpd-month-year) {
294
- color: white;
295
- font-weight: 600;
296
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
297
- }
298
-
299
- /* Weekday headers */
300
- .shamsi-date-picker :deep(.vpd-weekday) {
301
- color: rgb(var(--v-theme-primary));
302
- font-weight: 600;
303
- background: rgb(var(--v-theme-primaryContainer));
304
- border-radius: 6px;
305
- margin: 0px;
306
- }
307
-
308
- /* Footer buttons */
309
- .shamsi-date-picker :deep(.vpd-actions button) {
310
- background: rgb(var(--v-theme-secondary)) !important;
311
- color: white !important;
312
- border-radius: 8px;
313
- font-weight: 500;
314
- transition: all 0.2s ease;
315
- border: none;
316
- margin: 4px;
317
- }
318
-
319
- .shamsi-date-picker :deep(.vpd-actions button:hover) {
320
- background: rgb(var(--v-theme-primary)) !important;
321
- transform: translateY(-1px);
322
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
323
- }
324
-
325
- .shamsi-date-picker :deep(.vpd-actions button:active) {
326
- transform: translateY(0);
327
- }
328
-
329
- /* Responsive Design */
330
- @media (max-width: 768px) {
331
- .shamsi-date-picker :deep(.vpd-input-group) {
332
- border-radius: 8px;
333
- }
334
-
335
- .shamsi-date-picker :deep(.vpd-input-group input) {
336
- padding: 10px 12px;
337
- font-size: 14px;
338
- }
339
-
340
- .shamsi-date-picker :deep(.vpd-icon-btn) {
341
- padding: 6px;
342
- margin: 2px;
343
- min-width: 32px;
344
- min-height: 32px;
345
- display: flex;
346
- align-items: center;
347
- justify-content: center;
348
- }
349
-
350
- .shamsi-date-picker :deep(.vpd-icon-btn i) {
351
- font-size: 14px;
352
- }
353
-
354
- .shamsi-date-picker :deep(.vpd-picker) {
355
- max-width: 320px;
356
- margin: 0 auto;
357
- }
358
-
359
- .shamsi-date-picker :deep(.vpd-day) {
360
- padding: 8px 4px;
361
- font-size: 14px;
362
- min-width: 32px;
363
- min-height: 32px;
364
- display: flex;
365
- align-items: center;
366
- justify-content: center;
367
- }
368
-
369
- .shamsi-date-picker :deep(.vpd-weekday) {
370
- padding: 6px 2px;
371
- font-size: 12px;
372
- min-width: 28px;
373
- min-height: 28px;
374
- display: flex;
375
- align-items: center;
376
- justify-content: center;
377
- }
378
-
379
- .shamsi-date-picker :deep(.vpd-actions button) {
380
- padding: 6px 12px;
381
- font-size: 14px;
382
- margin: 2px;
383
- }
384
-
385
- .shamsi-date-picker :deep(.vpd-month-year) {
386
- font-size: 16px;
387
- }
388
-
389
- .shamsi-date-picker :deep(.vpd-nav-btn) {
390
- padding: 4px;
391
- min-width: 28px;
392
- min-height: 28px;
393
- display: flex;
394
- align-items: center;
395
- justify-content: center;
396
- }
397
- }
398
-
399
- @media (max-width: 480px) {
400
- .shamsi-date-picker :deep(.vpd-picker) {
401
- max-width: 280px;
402
- border-radius: 8px;
403
- }
404
-
405
- .shamsi-date-picker :deep(.vpd-day) {
406
- padding: 6px 2px;
407
- font-size: 12px;
408
- min-width: 28px;
409
- min-height: 28px;
410
- }
411
-
412
- .shamsi-date-picker :deep(.vpd-weekday) {
413
- padding: 4px 1px;
414
- font-size: 11px;
415
- min-width: 24px;
416
- min-height: 24px;
417
- }
418
-
419
- .shamsi-date-picker :deep(.vpd-actions button) {
420
- padding: 4px 8px;
421
- font-size: 12px;
422
- margin: 1px;
423
- }
424
-
425
- .shamsi-date-picker :deep(.vpd-month-year) {
426
- font-size: 14px;
427
- }
428
-
429
- .shamsi-date-picker :deep(.vpd-header) {
430
- border-radius: 8px 8px 0 0;
431
- }
432
- }
433
-
434
- /* Ensure proper touch targets on mobile */
435
- @media (hover: none) and (pointer: coarse) {
436
- .shamsi-date-picker :deep(.vpd-icon-btn),
437
- .shamsi-date-picker :deep(.vpd-day),
438
- .shamsi-date-picker :deep(.vpd-nav-btn),
439
- .shamsi-date-picker :deep(.vpd-actions button) {
440
- min-width: 44px;
441
- min-height: 44px;
442
- }
443
- }
444
- </style>
@@ -1,17 +0,0 @@
1
- <script setup lang="ts">
2
- const props = defineProps({
3
- title: String
4
- });
5
- </script>
6
-
7
- <template>
8
- <v-card variant="outlined">
9
- <v-card-item class="py-3">
10
- <v-card-title class="text-h5">{{ props.title }}</v-card-title>
11
- </v-card-item>
12
- <v-divider />
13
- <v-card-text>
14
- <slot />
15
- </v-card-text>
16
- </v-card>
17
- </template>
@@ -1,21 +0,0 @@
1
- <script setup lang="ts">
2
- const props = defineProps({
3
- title: String
4
- });
5
- </script>
6
-
7
- // ===============================|| Ui Parent Card||=============================== //
8
- <template>
9
- <v-card variant="flat">
10
- <v-card-item>
11
- <div class="d-sm-flex align-center justify-space-between">
12
- <v-card-title>{{ props.title }}</v-card-title>
13
- <slot name="action"></slot>
14
- </div>
15
- </v-card-item>
16
- <v-divider></v-divider>
17
- <v-card-text>
18
- <slot />
19
- </v-card-text>
20
- </v-card>
21
- </template>
@@ -1,136 +0,0 @@
1
- <script lang="ts" setup>
2
- import { computed, ref, watch, onMounted } from 'vue';
3
-
4
- // Your Regex for thousand separator
5
- const THOUSAND_SEPARATOR_REGEX = /\B(?=(\d{3})+(?!\d))/g;
6
-
7
- // Helper functions (previously in formatters.ts)
8
- const formatNumber = (value: string | number | undefined | null): string => {
9
- if (value === undefined || value === null || value === '') return '';
10
- const stringValue = value.toString().replace(/,/g, ''); // Remove existing commas
11
- if (stringValue === '') return '';
12
- return stringValue.replace(THOUSAND_SEPARATOR_REGEX, ',');
13
- };
14
-
15
- const unformatNumber = (value: string | undefined | null): string => {
16
- if (value === undefined || value === null) return '';
17
- return value.toString().replace(/,/g, '');
18
- };
19
-
20
- const props = defineProps<{
21
- modelValue: string | number | undefined | null; // The raw, unformatted numeric string or number
22
- label?: string;
23
- placeholder?: string;
24
- disabled?: boolean;
25
- readonly?: boolean;
26
- clearable?: boolean;
27
- errorMessages?: string | string[];
28
- min?: number; // For validation, not direct input blocking here
29
- max?: number; // For validation
30
- // Add any other v-text-field props you want to support
31
- }>();
32
-
33
- const emit = defineEmits<{
34
- (e: 'update:modelValue', value: string): void;
35
- (e: 'focus', event: FocusEvent): void;
36
- (e: 'blur', event: FocusEvent): void;
37
- }>();
38
-
39
- // Internal ref to manage the displayed (formatted) value in the text field
40
- const displayValue = ref('');
41
- const isFocused = ref(false);
42
-
43
- // When the underlying modelValue changes, update the displayValue (formatted)
44
- watch(() => props.modelValue, (newModelValue) => {
45
- if (!isFocused.value) {
46
- displayValue.value = formatNumber(newModelValue);
47
- } else {
48
- // If focused, the display value should be unformatted for editing
49
- // but ensure it syncs if modelValue changes externally while focused
50
- const unformattedModel = unformatNumber(newModelValue !== null && newModelValue !== undefined ? newModelValue.toString() : '');
51
- if (unformatNumber(displayValue.value) !== unformattedModel) {
52
- displayValue.value = unformattedModel;
53
- }
54
- }
55
- }, { immediate: true });
56
-
57
- onMounted(() => {
58
- displayValue.value = formatNumber(props.modelValue);
59
- });
60
-
61
- const handleInput = (event: Event) => {
62
- const inputElement = event.target as HTMLInputElement;
63
- let caretPosition = inputElement.selectionStart; // Store caret position
64
-
65
- let rawValue = inputElement.value;
66
- let unformatted = rawValue.replace(/[^\d]/g, ''); // Allow only digits
67
-
68
- // Handle min/max (simplified: primarily for validation, not strict input blocking here)
69
- if (props.min !== undefined && parseInt(unformatted, 10) < props.min) {
70
- // unformatted = props.min.toString(); // Could clamp, but might be jarring.
71
- }
72
- if (props.max !== undefined && parseInt(unformatted, 10) > props.max) {
73
- // unformatted = props.max.toString();
74
- }
75
-
76
- emit('update:modelValue', unformatted); // Emit the raw unformatted value
77
-
78
- // Update displayValue immediately with formatted version for the input field
79
- // This can be tricky with cursor position.
80
- const currentFormatted = formatNumber(unformatted);
81
-
82
- // Calculate difference in length to adjust caret
83
- const oldFormattedLength = displayValue.value.length;
84
- const newFormattedLength = currentFormatted.length;
85
-
86
- displayValue.value = currentFormatted; // Update internal display value
87
-
88
- // Attempt to restore caret position
89
- // This is a common challenge with formatted inputs.
90
- // Vue nextTick is important here to wait for DOM update.
91
- inputElement.value = currentFormatted; // Force update input element directly
92
- if (caretPosition !== null) {
93
- const diff = newFormattedLength - oldFormattedLength;
94
- try {
95
- inputElement.setSelectionRange(caretPosition + diff, caretPosition + diff);
96
- } catch (e) {
97
- // Some browsers might have issues if not fully visible or other edge cases
98
- }
99
- }
100
- };
101
-
102
- const handleFocus = (event: FocusEvent) => {
103
- isFocused.value = true;
104
- displayValue.value = unformatNumber(props.modelValue !== null && props.modelValue !== undefined ? props.modelValue.toString() : ''); // Show raw number for editing
105
- emit('focus', event);
106
- };
107
-
108
- const handleBlur = (event: FocusEvent) => {
109
- isFocused.value = false;
110
- displayValue.value = formatNumber(props.modelValue); // Format on blur
111
- emit('blur', event);
112
- };
113
-
114
- </script>
115
-
116
- <template>
117
- <v-text-field
118
- :model-value="displayValue"
119
- :label="props.label"
120
- :placeholder="props.placeholder"
121
- :disabled="props.disabled"
122
- :readonly="props.readonly"
123
- :clearable="props.clearable"
124
- :error-messages="props.errorMessages"
125
- @input="handleInput"
126
- @focus="handleFocus"
127
- @blur="handleBlur"
128
- inputmode="numeric"
129
- pattern="[0-9,]*"
130
- >
131
- <!-- Pass through slots if needed -->
132
- <template v-for="(_, slot) in $slots" #[slot]="scope">
133
- <slot :name="slot" v-bind="scope || {}" />
134
- </template>
135
- </v-text-field>
136
- </template>