feat(ui) : MalioDate/DateTime exposent update:valid + saisie clavier DateTime (#MUI-43)
- MalioDate : event update:valid (malforme/hors-plage => false), emis au montage - MalioDateTime : prop editable (saisie JJ/MM/AAAA HH:MM) + meme update:valid - CalendarField : masque maska configurable via prop mask - datetimeFormat : nouveau parseur parseDisplayToIsoDateTime - fix test Date « Entree » (key 'Enter' reel vs trigger keydown.enter) - doc COMPONENTS.md + CHANGELOG.md + champ editable dans le playground Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import {
|
||||
composeDateTime,
|
||||
formatIsoDateTimeToDisplay,
|
||||
isValidIsoDateTime,
|
||||
parseDisplayToIsoDateTime,
|
||||
splitDateTime,
|
||||
} from './datetimeFormat'
|
||||
|
||||
@@ -49,6 +50,34 @@ describe('datetimeFormat', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('parseDisplayToIsoDateTime', () => {
|
||||
it('parse un JJ/MM/AAAA HH:MM valide en datetime ISO', () => {
|
||||
expect(parseDisplayToIsoDateTime('20/05/2026 14:30')).toBe('2026-05-20T14:30:00')
|
||||
expect(parseDisplayToIsoDateTime('01/01/2026 00:00')).toBe('2026-01-01T00:00:00')
|
||||
expect(parseDisplayToIsoDateTime('31/12/2026 23:59')).toBe('2026-12-31T23:59:00')
|
||||
})
|
||||
|
||||
it('tolère les espaces autour', () => {
|
||||
expect(parseDisplayToIsoDateTime(' 20/05/2026 14:30 ')).toBe('2026-05-20T14:30:00')
|
||||
})
|
||||
|
||||
it('rejette une date malformée', () => {
|
||||
expect(parseDisplayToIsoDateTime('32/01/2026 10:00')).toBeNull()
|
||||
expect(parseDisplayToIsoDateTime('10/13/2026 10:00')).toBeNull()
|
||||
})
|
||||
|
||||
it('rejette une heure hors bornes', () => {
|
||||
expect(parseDisplayToIsoDateTime('20/05/2026 24:00')).toBeNull()
|
||||
expect(parseDisplayToIsoDateTime('20/05/2026 12:60')).toBeNull()
|
||||
})
|
||||
|
||||
it('rejette un format incomplet ou sans heure', () => {
|
||||
expect(parseDisplayToIsoDateTime('20/05/2026')).toBeNull()
|
||||
expect(parseDisplayToIsoDateTime('20/05/2026 14')).toBeNull()
|
||||
expect(parseDisplayToIsoDateTime('')).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe('composeDateTime', () => {
|
||||
it('recompose un datetime ISO avec secondes à 00', () => {
|
||||
expect(composeDateTime('2026-05-20', '14:30')).toBe('2026-05-20T14:30:00')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {isValidIso} from './dateFormat'
|
||||
import {isValidIso, parseDisplayToIso} from './dateFormat'
|
||||
|
||||
const DATETIME_RE = /^(\d{4}-\d{2}-\d{2})T(\d{2}):(\d{2}):(\d{2})$/
|
||||
|
||||
@@ -27,6 +27,16 @@ export function splitDateTime(s: string | null): {date: string | null; time: str
|
||||
return {date, time: time.slice(0, 5)}
|
||||
}
|
||||
|
||||
export function parseDisplayToIsoDateTime(display: string): string | null {
|
||||
const match = /^(\d{2}\/\d{2}\/\d{4}) (\d{2}):(\d{2})$/.exec(display.trim())
|
||||
if (!match) return null
|
||||
const [, datePart, hh, mm] = match
|
||||
const iso = parseDisplayToIso(datePart)
|
||||
if (!iso) return null
|
||||
if (Number(hh) > 23 || Number(mm) > 59) return null
|
||||
return `${iso}T${hh}:${mm}:00`
|
||||
}
|
||||
|
||||
export function composeDateTime(date: string, time: string): string {
|
||||
const t = time || '00:00'
|
||||
return `${date}T${t}:00`
|
||||
|
||||
Reference in New Issue
Block a user