@ramathibodi/nuxt-commons 0.1.53 → 0.1.54

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.
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": "^3.0.0"
6
6
  },
7
- "version": "0.1.53",
7
+ "version": "0.1.54",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "0.8.4",
10
10
  "unbuild": "2.0.0"
@@ -3,7 +3,7 @@ import {computed, ref, watch} from 'vue'
3
3
  import * as prettier from 'prettier'
4
4
  import prettierPluginHtml from 'prettier/plugins/html'
5
5
  import {useDocumentTemplate, validationRulesRegex,optionStringToChoiceObject} from '../../composables/document/template'
6
- import {cloneDeep} from "lodash-es";
6
+ import {cloneDeep , filter} from "lodash-es";
7
7
 
8
8
  interface Props {
9
9
  title?: string
@@ -342,14 +342,14 @@ const ruleOptions = (inputType: string) => (value: any) => {
342
342
  </v-container>
343
343
  </template>
344
344
 
345
- <template v-for="header of useFilter(optionData.headers,(item)=> item.template)" #[`item.${header.key}`]="{item}">
345
+ <template v-for="header of filter(optionData.headers,(item)=> item.template)" #[`item.${header.key}`]="{item}">
346
346
  <form-pad
347
347
  :template="header.template"
348
348
  v-model="item[header.key]">
349
349
  </form-pad>
350
350
 
351
351
  </template>
352
- <template v-for="header of useFilter(optionData.headers,(item)=> item.headerTemplate)" #[`header.${header.key}`]="{item}">
352
+ <template v-for="header of filter(optionData.headers,(item)=> item.headerTemplate)" #[`header.${header.key}`]="{item}">
353
353
  <form-pad
354
354
  :template="header.headerTemplate"
355
355
  >
@@ -1,41 +1,92 @@
1
1
  <script setup lang="ts">
2
- import { DateTime, type ToRelativeOptions } from "luxon";
2
+ import { DateTime } from "luxon";
3
3
  import { computed } from "vue";
4
4
 
5
+ type Unit = 'years' | 'months' | 'days' | 'hours' | 'minutes' | 'seconds';
6
+ type Locale = 'th' | 'en' | 'en-US' | 'th-TH';
7
+
5
8
  interface Props {
6
9
  modelValue: DateTime;
7
- locale?: 'TH' | 'EN';
10
+ locale?: Locale;
11
+ showSuffix?: boolean;
12
+ units?: Unit[];
8
13
  }
9
14
 
10
15
  const props = withDefaults(defineProps<Props>(), {
11
- locale: 'TH',
16
+ locale: 'th',
17
+ showSuffix: true
12
18
  });
13
19
 
14
- const timeAgo = computed(() => {
20
+ // Fallback map: map complex locale (e.g., en-US) to base (e.g., en)
21
+ const normalizeLocale = (locale: Locale): 'en' | 'th' => {
22
+ if (locale.startsWith('en')) return 'en';
23
+ if (locale.startsWith('th')) return 'th';
24
+ return 'th'; // default fallback
25
+ };
26
+
27
+ const localizedLabels: Record<'en' | 'th', Record<Unit, string>> = {
28
+ en: {
29
+ years: 'years',
30
+ months: 'months',
31
+ days: 'days',
32
+ hours: 'hours',
33
+ minutes: 'minutes',
34
+ seconds: 'seconds',
35
+ },
36
+ th: {
37
+ years: 'ปี',
38
+ months: 'เดือน',
39
+ days: 'วัน',
40
+ hours: 'ชั่วโมง',
41
+ minutes: 'นาที',
42
+ seconds: 'วินาที',
43
+ },
44
+ };
45
+
46
+ const localizedSuffix: Record<'en' | 'th', string> = {
47
+ en: 'ago',
48
+ th: 'ที่ผ่านมา',
49
+ };
50
+
51
+ const outputText = computed(() => {
15
52
  const now = DateTime.now();
16
- const diff = now.diff(props.modelValue, ['years', 'months', 'days', 'hours', 'minutes', 'seconds']).toObject();
17
-
18
- let unit: ToRelativeOptions['unit'] = 'seconds';
19
- if (diff.years && diff.years > 0) {
20
- unit = 'years';
21
- } else if (diff.months && diff.months > 0) {
22
- unit = 'months';
23
- } else if (diff.days && diff.days > 0) {
24
- unit = 'days';
25
- } else if (diff.hours && diff.hours > 0) {
26
- unit = 'hours';
27
- } else if (diff.minutes && diff.minutes > 0) {
28
- unit = 'minutes';
53
+ const baseLocale = normalizeLocale(props.locale);
54
+
55
+ const units: Unit[] = props.units?.length
56
+ ? props.units
57
+ : ['years', 'months', 'days', 'hours', 'minutes', 'seconds'];
58
+
59
+ const diff = now.diff(props.modelValue, units).toObject();
60
+
61
+ if (!props.units) {
62
+ const foundUnit = units.find(unit => (diff[unit] ?? 0) >= 1);
63
+ const value = Math.floor(diff[foundUnit!] ?? 0);
64
+ const label = localizedLabels[baseLocale][foundUnit!];
65
+ const suffix = props.showSuffix ? localizedSuffix[baseLocale] : '';
66
+ return `${value} ${label}${suffix}`;
67
+ }
68
+
69
+ const parts = units.map(unit => {
70
+ const value = Math.floor(diff[unit] ?? 0);
71
+ if (value > 0) {
72
+ const label = localizedLabels[baseLocale][unit];
73
+ return `${value} ${label}`;
74
+ }
75
+ return '';
76
+ }).filter(Boolean);
77
+
78
+ if (parts.length === 0) {
79
+ const lastUnit = units.at(-1)!;
80
+ const label = localizedLabels[baseLocale][lastUnit];
81
+ const suffix = props.showSuffix ? localizedSuffix[baseLocale] : '';
82
+ return `0 ${label} ${suffix}`;
29
83
  }
30
84
 
31
- return props.modelValue.setLocale(props.locale).toRelative({ unit });
85
+ const suffix = props.showSuffix ? localizedSuffix[baseLocale] : '';
86
+ return `${parts.join(' ')} ${suffix}`;
32
87
  });
33
88
  </script>
34
89
 
35
90
  <template>
36
- <span>{{ timeAgo }}</span>
91
+ <span>{{ outputText }}</span>
37
92
  </template>
38
-
39
- <style scoped>
40
-
41
- </style>
@@ -36,7 +36,7 @@ const modelItemValue = computedAsync<string>(async () => {
36
36
  }
37
37
  }
38
38
  return props.notFoundText
39
- }, props.placeholder )
39
+ }, props.placeholder ?? '' )
40
40
  </script>
41
41
 
42
42
  <template>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ramathibodi/nuxt-commons",
3
- "version": "0.1.53",
3
+ "version": "0.1.54",
4
4
  "description": "Ramathibodi Nuxt modules for common components",
5
5
  "repository": {
6
6
  "type": "git",