@polymarbot/nuxt-layer-shadcn-ui 0.8.6 → 0.8.7
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.
|
@@ -18,7 +18,7 @@ export interface DatePickerTimeConfig {
|
|
|
18
18
|
export type DatePickerType = 'date' | 'month' | 'year'
|
|
19
19
|
|
|
20
20
|
export interface DatePickerProps {
|
|
21
|
-
modelValue?: Date | string | null
|
|
21
|
+
modelValue?: Date | string | number | null
|
|
22
22
|
/** Picker type: date (default), month, or year */
|
|
23
23
|
type?: DatePickerType
|
|
24
24
|
/** Enable time selection, or pass DatePickerTimeConfig for fine-grained control */
|
|
@@ -33,7 +33,11 @@ export interface DatePickerProps {
|
|
|
33
33
|
minDate?: Date | string
|
|
34
34
|
/** Maximum selectable date */
|
|
35
35
|
maxDate?: Date | string
|
|
36
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* v-model output format. Accepts any VueDatePicker `model-type` value:
|
|
38
|
+
* `'iso'`, `'timestamp'`, or a date-fns pattern (e.g. `'yyyy-MM-dd'`).
|
|
39
|
+
* Omit to bind a `Date` object.
|
|
40
|
+
*/
|
|
37
41
|
valueFormat?: string
|
|
38
42
|
/** Auto apply selection without confirm button */
|
|
39
43
|
autoApply?: boolean
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { DateRangePickerProps } from './types'
|
|
3
|
+
import { format as formatDate, parse as parseDate } from 'date-fns'
|
|
3
4
|
|
|
4
5
|
defineOptions({ inheritAttrs: false })
|
|
5
6
|
|
|
@@ -20,30 +21,65 @@ const props = withDefaults(defineProps<DateRangePickerProps>(), {
|
|
|
20
21
|
})
|
|
21
22
|
|
|
22
23
|
const emit = defineEmits<{
|
|
23
|
-
'update:start': [value: Date | string | null]
|
|
24
|
-
'update:end': [value: Date | string | null]
|
|
24
|
+
'update:start': [value: Date | string | number | null]
|
|
25
|
+
'update:end': [value: Date | string | number | null]
|
|
25
26
|
}>()
|
|
26
27
|
|
|
27
28
|
const { t } = useI18n()
|
|
28
29
|
const T = useTranslations('components.ui.DateRangePicker')
|
|
29
30
|
|
|
31
|
+
// Convert a v-model value (whose shape depends on valueFormat) into a Date for manipulation.
|
|
32
|
+
function parseValue (value: Date | string | number): Date | null {
|
|
33
|
+
if (value instanceof Date) return new Date(value)
|
|
34
|
+
if (typeof value === 'number') return new Date(value)
|
|
35
|
+
const fmt = props.valueFormat
|
|
36
|
+
if (!fmt || fmt === 'iso') return new Date(value)
|
|
37
|
+
if (fmt === 'timestamp') return new Date(Number(value))
|
|
38
|
+
if (fmt === 'format') return null // uses VueDatePicker `format` prop, not exposed here
|
|
39
|
+
try {
|
|
40
|
+
return parseDate(value, fmt, new Date())
|
|
41
|
+
} catch {
|
|
42
|
+
return null
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Convert a Date back to the same shape as the original value.
|
|
47
|
+
function formatValue (date: Date, original: Date | string | number): Date | string | number {
|
|
48
|
+
if (original instanceof Date) return date
|
|
49
|
+
if (typeof original === 'number') return date.getTime()
|
|
50
|
+
const fmt = props.valueFormat
|
|
51
|
+
if (!fmt || fmt === 'iso') return date.toISOString()
|
|
52
|
+
if (fmt === 'timestamp') return date.getTime()
|
|
53
|
+
if (fmt === 'format') return original
|
|
54
|
+
try {
|
|
55
|
+
return formatDate(date, fmt)
|
|
56
|
+
} catch {
|
|
57
|
+
return original
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Normalize the time portion to start/end of day so the range is inclusive.
|
|
62
|
+
// For date-only patterns (e.g. 'yyyy-MM-dd') the output is unchanged since the
|
|
63
|
+
// formatted string carries no time component — the round-trip just preserves it.
|
|
64
|
+
function normalizeTimeOfDay (
|
|
65
|
+
value: Date | string | number | null,
|
|
66
|
+
end: boolean,
|
|
67
|
+
): Date | string | number | null {
|
|
68
|
+
if (value == null) return value
|
|
69
|
+
const date = parseValue(value)
|
|
70
|
+
if (!date || Number.isNaN(date.getTime())) return value
|
|
71
|
+
date.setHours(end ? 23 : 0, end ? 59 : 0, end ? 59 : 0, end ? 999 : 0)
|
|
72
|
+
return formatValue(date, value)
|
|
73
|
+
}
|
|
74
|
+
|
|
30
75
|
const start = computed({
|
|
31
76
|
get: () => props.start,
|
|
32
|
-
set: value => emit('update:start', value),
|
|
77
|
+
set: value => emit('update:start', props.showTime ? value : normalizeTimeOfDay(value, false)),
|
|
33
78
|
})
|
|
34
79
|
|
|
35
80
|
const end = computed({
|
|
36
81
|
get: () => props.end,
|
|
37
|
-
set: value =>
|
|
38
|
-
// When time is disabled, normalize end to end of day so range is inclusive
|
|
39
|
-
if (value instanceof Date && !props.showTime) {
|
|
40
|
-
const adjusted = new Date(value)
|
|
41
|
-
adjusted.setHours(23, 59, 59, 999)
|
|
42
|
-
emit('update:end', adjusted)
|
|
43
|
-
} else {
|
|
44
|
-
emit('update:end', value)
|
|
45
|
-
}
|
|
46
|
-
},
|
|
82
|
+
set: value => emit('update:end', props.showTime ? value : normalizeTimeOfDay(value, true)),
|
|
47
83
|
})
|
|
48
84
|
|
|
49
85
|
function addDays (date: Date, days: number): Date {
|
|
@@ -52,9 +88,10 @@ function addDays (date: Date, days: number): Date {
|
|
|
52
88
|
return result
|
|
53
89
|
}
|
|
54
90
|
|
|
55
|
-
function toDate (value: Date | string | null | undefined): Date | undefined {
|
|
56
|
-
if (
|
|
57
|
-
|
|
91
|
+
function toDate (value: Date | string | number | null | undefined): Date | undefined {
|
|
92
|
+
if (value == null) return undefined
|
|
93
|
+
if (value instanceof Date) return value
|
|
94
|
+
return parseValue(value) ?? undefined
|
|
58
95
|
}
|
|
59
96
|
|
|
60
97
|
const startMinDate = computed(() => {
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import type { DatePickerTimeConfig } from '../DatePicker/types'
|
|
2
2
|
|
|
3
3
|
export interface DateRangePickerProps {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Range start. When `showTime` is false, the emitted value is normalized to
|
|
6
|
+
* the start of the day (00:00:00.000) so the range is inclusive.
|
|
7
|
+
*/
|
|
8
|
+
start?: Date | string | number | null
|
|
9
|
+
/**
|
|
10
|
+
* Range end. When `showTime` is false, the emitted value is normalized to
|
|
11
|
+
* the end of the day (23:59:59.999) so the range is inclusive.
|
|
12
|
+
*/
|
|
13
|
+
end?: Date | string | number | null
|
|
6
14
|
/** Minimum selectable date */
|
|
7
15
|
minDate?: Date | string
|
|
8
16
|
/** Maximum selectable date */
|
|
@@ -19,7 +27,11 @@ export interface DateRangePickerProps {
|
|
|
19
27
|
endPlaceholder?: string
|
|
20
28
|
/** Maximum span in days between start and end date */
|
|
21
29
|
maxSpanDays?: number
|
|
22
|
-
/**
|
|
30
|
+
/**
|
|
31
|
+
* v-model output format. Accepts any VueDatePicker `model-type` value:
|
|
32
|
+
* `'iso'`, `'timestamp'`, or a date-fns pattern (e.g. `'yyyy-MM-dd'`).
|
|
33
|
+
* Omit to bind a `Date` object.
|
|
34
|
+
*/
|
|
23
35
|
valueFormat?: string
|
|
24
36
|
/** Auto apply selection without confirm button */
|
|
25
37
|
autoApply?: boolean
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@polymarbot/nuxt-layer-shadcn-ui",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.7",
|
|
4
4
|
"description": "Nuxt layer providing shadcn-vue based UI components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./nuxt.config.ts",
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"vue-i18n": "^11",
|
|
43
43
|
"vue-router": "^4 || ^5"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "1f8a4521c7e52de4063c33f47888be48cc99329b"
|
|
46
46
|
}
|