feat(12.2-04): add the datepicker field and stored date and time list cells
- pin @internationalized/date 3.12.4 as a direct admin dependency (approved) - dateFormat.ts parses and emits date, datetime (local display, UTC emit, ignoreTimezone wall clock) and time values without the global Date - DatepickerField on Reka DatePicker and TimeField with locale segments, calendar popover, clear button, min/max and yearRange bounds - list cells of type date and time render the stored string - datepicker lang keys in en and pl; rebuilt boardwalk dist
This commit is contained in:
@@ -7,6 +7,9 @@ import { t } from '../../app/i18n'
|
||||
// One cell rendered by column type (D-12): text by default (arrays
|
||||
// comma-joined, a muted dash when empty), datetime as YYYY-MM-DD HH:mm with
|
||||
// tabular numbers, switch as the Tak/Nie pills. No per-value icon pills.
|
||||
// Phase 12.2: a `date` column shows the stored YYYY-MM-DD and a `time`
|
||||
// column the stored HH:mm, both as strings: a calendar date or a time of day
|
||||
// has no zone, so it never goes through the global Date (Pitfall 12).
|
||||
const props = defineProps<{ column: ListColumn; value: unknown }>()
|
||||
|
||||
function isEmpty(value: unknown): boolean {
|
||||
@@ -44,6 +47,24 @@ function datetime(value: unknown): string {
|
||||
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`
|
||||
}
|
||||
|
||||
/** A stored date as-is (YYYY-MM-DD); anything after the day is dropped. */
|
||||
function storedDate(value: unknown): string {
|
||||
if (typeof value !== 'string') {
|
||||
return ''
|
||||
}
|
||||
const match = /^\d{4}-\d{2}-\d{2}/.exec(value.trim())
|
||||
return match ? match[0] : value.trim()
|
||||
}
|
||||
|
||||
/** A stored time of day as HH:mm (seconds dropped). */
|
||||
function storedTime(value: unknown): string {
|
||||
if (typeof value !== 'string') {
|
||||
return ''
|
||||
}
|
||||
const match = /(\d{2}):(\d{2})/.exec(value)
|
||||
return match ? `${match[1]}:${match[2]}` : value.trim()
|
||||
}
|
||||
|
||||
function truthy(value: unknown): boolean {
|
||||
if (typeof value === 'string') {
|
||||
return value !== '' && value !== '0' && value.toLowerCase() !== 'false'
|
||||
@@ -58,10 +79,27 @@ const kind = computed(() => {
|
||||
if (props.column.type === 'datetime') {
|
||||
return 'datetime'
|
||||
}
|
||||
if (props.column.type === 'date') {
|
||||
return 'date'
|
||||
}
|
||||
if (props.column.type === 'time') {
|
||||
return 'time'
|
||||
}
|
||||
return 'text'
|
||||
})
|
||||
|
||||
const display = computed(() => (kind.value === 'datetime' ? datetime(props.value) : text(props.value)))
|
||||
const display = computed(() => {
|
||||
switch (kind.value) {
|
||||
case 'datetime':
|
||||
return datetime(props.value)
|
||||
case 'date':
|
||||
return storedDate(props.value)
|
||||
case 'time':
|
||||
return storedTime(props.value)
|
||||
default:
|
||||
return text(props.value)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -81,6 +119,6 @@ const display = computed(() => (kind.value === 'datetime' ? datetime(props.value
|
||||
>
|
||||
</template>
|
||||
<span v-else-if="display === ''" class="text-muted" data-empty>—</span>
|
||||
<span v-else-if="kind === 'datetime'" class="text-[13px] text-muted tabular-nums">{{ display }}</span>
|
||||
<span v-else-if="kind === 'datetime' || kind === 'date' || kind === 'time'" class="text-[13px] text-muted tabular-nums">{{ display }}</span>
|
||||
<template v-else>{{ display }}</template>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user