Skip to content

feat: #ENABLING-645 complete the useDate hook with date format spec methods - #520

Open
pascalsaussier-edifice wants to merge 1 commit into
develop-enablingfrom
feat-ENABLING-645-complete-usedate-hook
Open

feat: #ENABLING-645 complete the useDate hook with date format spec methods#520
pascalsaussier-edifice wants to merge 1 commit into
develop-enablingfrom
feat-ENABLING-645-complete-usedate-hook

Conversation

@pascalsaussier-edifice

@pascalsaussier-edifice pascalsaussier-edifice commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

Description

Complète le hook useDate (@edifice.io/react) en exposant une méthode par format du design system de dates, plus des helpers de conversion. Objectif : harmoniser l'affichage des dates dans les nouvelles apps et arrêter les réimplémentations locales.

Changement non-breaking : ajout de méthodes ; les anciennes (fromNow, formatTimeAgo, formatDate) restent fonctionnelles et sont annotées @deprecated.

Changements

Nouveaux formatters (tous acceptent un CoreDate, localisés via currentLanguage) :

Méthode Format spec Exemple (fr)
formatRelativeDateTime Convivial — avec heure hier à 16h22, le 21 septembre à 16h22
formatRelativeDate Convivial — sans heure il y a 38 minutes, hier, 21 sept.
formatLongDateTime Simple & textuel — avec heure 23 juillet 2021 à 17:46
formatLongDate Simple & textuel — sans heure 23 juillet 2021
formatRawDate Brut — sans heure 28/02/2025
formatRawDateTime Brut — avec heure 18/11/2019 15:36
formatCalendarDate(date, variant) Calendrier ('full' | 'short' | 'abbr') vendredi 16 avril, 12 janv., 16/04
formatWeek Semaine Cette semaine, Semaine du 17 au 23 janvier

Conversions : toJsDate, toTimestamp, toIsoDate, toMongoDate (robustes aux entrées invalides → undefined).

Autres :

  • Dépréciation (@deprecated JSDoc) de fromNowformatRelativeDateTime, formatTimeAgoformatRelativeDate, formatDateformatLongDate/formatRawDate/formatCalendarDate.
  • Pilotage 100 % i18n (patterns dayjs + libellés) : clés date.* ajoutées en en et fr dans apps/docs/i18n.ts. Aucun texte en dur.
  • Correction des imports dayjs isSameOrAfter/isToday (ajout de l'extension .js) pour qu'ils restent externalisés en imports propres dayjs/plugin/xxx.js au lieu d'un chemin pnpm absolu.

Audit poids : aucun plugin dayjs ajouté (implémentation basée sur le built-in startOf('week') + comparaisons). dayjs et ses plugins sont externalisés par le build → 0 octet ajouté au bundle publié.

Choix d'implémentation (spec ambiguë)

  • Bascule relatif → date des formats conviviaux fixée à 3 h ; lignes barrées de la spec ignorées.
  • Casse des jours/mois laissée telle que produite par dayjs (ex. mercredi à 16h22).
  • formatWeek : bornes en mois abrégé pour semaine dernière/prochaine, mois complet pour « Semaine du … ».

Which Package changed?

  • Components
  • Core
  • Icons
  • Hooks

@edifice.io/react (hook + tests + doc) et clés i18n de référence dans apps/docs.

Has the documentation changed?

  • Storybook

useDate.mdx refait (tableaux des méthodes / conversions / comparaisons / dépréciations).

Type of change

  • Chore (PATCH)
  • Doc (PATCH)
  • Bug fix (PATCH)
  • New feature (MINOR)
  • Breaking change (MAJOR)

Comment tester

  1. pnpm --filter @edifice.io/react test → 152 tests OK (dont 20 sur useDate).
  2. pnpm docs puis Hooks / useDate pour la doc.
  3. Vérifier les sorties FR de chaque méthode contre les exemples de la spec.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR completes the useDate hook in @edifice.io/react by adding one formatter per design-system date format (friendly/simple/raw/calendar/week), plus robust conversion helpers, while keeping the previous API available via @deprecated methods.

Changes:

  • Added new date-format methods (formatRelativeDate(Time), formatLongDate(Time), formatRawDate(Time), formatCalendarDate, formatWeek) and conversion helpers (toJsDate, toTimestamp, toIsoDate, toMongoDate).
  • Added Vitest coverage for the new API surface and ensured deprecated methods still behave as before.
  • Added date.* i18n keys for EN/FR in the docs app and updated useDate Storybook documentation.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 8 comments.

File Description
packages/react/src/hooks/useDate/useDate.ts Implements the new formatters/converters and updates dayjs plugin imports to include .js.
packages/react/src/hooks/useDate/useDate.spec.tsx Adds tests validating new formatters, conversions, and deprecated method compatibility.
packages/react/src/hooks/useDate/useDate.mdx Updates Storybook docs to describe the new API and deprecations.
apps/docs/i18n.ts Adds EN/FR date.* keys used by the new formatters in the docs environment.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +44 to +47
* Beyond this duration (in hours), friendly formats stop using a relative
* wording ("3 hours ago") and switch to a day-based wording ("yesterday",
* weekday, date). Matches the date format spec.
*/
Comment on lines +144 to +166
computedDate.isToday() ||
Math.abs(now.diff(computedDate, 'hour')) <= FRIENDLY_RELATIVE_MAX_HOURS
) {
return computedDate.fromNow();
}

let patternKey: string;
if (computedDate.isSame(now.subtract(1, 'day'), 'day')) {
patternKey = 'yesterday';
} else if (computedDate.isSame(now.add(1, 'day'), 'day')) {
patternKey = 'tomorrow';
} else if (Math.abs(now.diff(computedDate, 'day')) < 7) {
patternKey = 'weekday';
} else if (computedDate.isSame(now, 'year')) {
patternKey = 'currentYear';
} else {
patternKey = 'otherYear';
}

return computedDate.format(t(`date.friendly.${keyPrefix}.${patternKey}`));
},
[toComputedDate, t],
);
Comment on lines +195 to +203
const formatLongDateTime = useCallback(
(date: CoreDate): string => {
const computedDate = toComputedDate(date);
return computedDate?.isValid()
? computedDate.format(t('date.long.datetime'))
: '';
},
[toComputedDate, t],
);
Comment on lines +211 to +219
const formatLongDate = useCallback(
(date: CoreDate): string => {
const computedDate = toComputedDate(date);
return computedDate?.isValid()
? computedDate.format(t('date.long.date'))
: '';
},
[toComputedDate, t],
);
Comment on lines +226 to +234
const formatRawDate = useCallback(
(date: CoreDate): string => {
const computedDate = toComputedDate(date);
return computedDate?.isValid()
? computedDate.format(t('date.raw.date'))
: '';
},
[toComputedDate, t],
);
Comment on lines +241 to +249
const formatRawDateTime = useCallback(
(date: CoreDate): string => {
const computedDate = toComputedDate(date);
return computedDate?.isValid()
? computedDate.format(t('date.raw.datetime'))
: '';
},
[toComputedDate, t],
);
Comment on lines +271 to +278
const period = computedDate.isSame(now, 'year')
? 'currentYear'
: 'otherYear';

return computedDate.format(t(`date.calendar.${variant}.${period}`));
},
[toComputedDate, t],
);
Comment on lines +291 to +294
const now = dayjs().locale(currentLanguage as string);
const targetWeekStart = computedDate.startOf('week');
const weekDiff = targetWeekStart.diff(now.startOf('week'), 'week');

@pascalsaussier-edifice
pascalsaussier-edifice force-pushed the feat-ENABLING-645-complete-usedate-hook branch from 9dad3e9 to 4448443 Compare June 25, 2026 12:28
damienromito
damienromito previously approved these changes Jun 30, 2026

@damienromito damienromito left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

propre ! c'est une bonne pratique de commencer à deprecier , ça nous facilitera le travail. Par contre il faudra ajouter une tâche de migration/clean sinon on va rester comme ça très longtemps.

@pascalsaussier-edifice
pascalsaussier-edifice force-pushed the develop-enabling branch 2 times, most recently from ab73b57 to 434033a Compare July 1, 2026 09:29
@pascalsaussier-edifice
pascalsaussier-edifice force-pushed the feat-ENABLING-645-complete-usedate-hook branch from 4448443 to 1df492b Compare July 1, 2026 13:27
@pascalsaussier-edifice
pascalsaussier-edifice force-pushed the feat-ENABLING-645-complete-usedate-hook branch from 1df492b to 4913f4c Compare July 16, 2026 13:47
@pascalsaussier-edifice
pascalsaussier-edifice force-pushed the feat-ENABLING-645-complete-usedate-hook branch from 4913f4c to b6be60e Compare July 27, 2026 15:36
@pascalsaussier-edifice
pascalsaussier-edifice force-pushed the feat-ENABLING-645-complete-usedate-hook branch 2 times, most recently from b52d01d to fbdc1bf Compare August 6, 2026 13:19
jcbe-ode
jcbe-ode previously approved these changes Aug 13, 2026
@pascalsaussier-edifice
pascalsaussier-edifice dismissed jcbe-ode’s stale review August 25, 2026 15:19

The merge-base changed after approval.

…ethods

Expose one method per format of the Edifice date format spec, plus
conversion helpers, so apps stop reimplementing date formatting.

- Friendly: formatRelativeDateTime, formatRelativeDate
- Simple/textual: formatLongDateTime, formatLongDate
- Raw: formatRawDate, formatRawDateTime
- Calendar: formatCalendarDate(variant 'full' | 'short' | 'abbr')
- Week: formatWeek
- Conversions: toJsDate, toTimestamp, toIsoDate, toMongoDate
- Deprecate fromNow/formatTimeAgo/formatDate (kept, non-breaking)
- Drive all wordings/patterns from i18n (en + fr reference keys), no
  hardcoded text
- Fix isSameOrAfter/isToday dayjs imports to use the .js extension so
  they stay externalized as clean imports
- Add useDate unit tests (frozen now, fr locale) and refresh the mdx doc

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@pascalsaussier-edifice
pascalsaussier-edifice force-pushed the feat-ENABLING-645-complete-usedate-hook branch from fbdc1bf to a1ebd74 Compare August 26, 2026 15:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants