@cdx-ui/formatters 0.0.1-beta.132
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/README.md +108 -0
- package/lib/commonjs/dates/calendar/formatCalendarMonthYear.js +28 -0
- package/lib/commonjs/dates/calendar/formatCalendarMonthYear.js.map +1 -0
- package/lib/commonjs/dates/calendar/formatDateTimeListDateRow.js +40 -0
- package/lib/commonjs/dates/calendar/formatDateTimeListDateRow.js.map +1 -0
- package/lib/commonjs/dates/calendar/formatMonthCalendarMonth.js +28 -0
- package/lib/commonjs/dates/calendar/formatMonthCalendarMonth.js.map +1 -0
- package/lib/commonjs/dates/calendar/formatMonthCalendarYear.js +16 -0
- package/lib/commonjs/dates/calendar/formatMonthCalendarYear.js.map +1 -0
- package/lib/commonjs/dates/calendar/getCalendarWeekdayLabels.js +23 -0
- package/lib/commonjs/dates/calendar/getCalendarWeekdayLabels.js.map +1 -0
- package/lib/commonjs/dates/datetime/clampDateTimeId.js +27 -0
- package/lib/commonjs/dates/datetime/clampDateTimeId.js.map +1 -0
- package/lib/commonjs/dates/datetime/compareDateTimeIds.js +28 -0
- package/lib/commonjs/dates/datetime/compareDateTimeIds.js.map +1 -0
- package/lib/commonjs/dates/datetime/dateTimeId.js +38 -0
- package/lib/commonjs/dates/datetime/dateTimeId.js.map +1 -0
- package/lib/commonjs/dates/datetime/formatDateTimeId.js +27 -0
- package/lib/commonjs/dates/datetime/formatDateTimeId.js.map +1 -0
- package/lib/commonjs/dates/datetime/formatDateTimeListHour.js +21 -0
- package/lib/commonjs/dates/datetime/formatDateTimeListHour.js.map +1 -0
- package/lib/commonjs/dates/datetime/formatDateTimeListMinute.js +16 -0
- package/lib/commonjs/dates/datetime/formatDateTimeListMinute.js.map +1 -0
- package/lib/commonjs/dates/datetime/formatDateTimeListPeriod.js +17 -0
- package/lib/commonjs/dates/datetime/formatDateTimeListPeriod.js.map +1 -0
- package/lib/commonjs/dates/datetime/isLocaleHour12.js +30 -0
- package/lib/commonjs/dates/datetime/isLocaleHour12.js.map +1 -0
- package/lib/commonjs/dates/datetime/isValidDateTimeId.js +23 -0
- package/lib/commonjs/dates/datetime/isValidDateTimeId.js.map +1 -0
- package/lib/commonjs/dates/datetime/nowDateTimeId.js +57 -0
- package/lib/commonjs/dates/datetime/nowDateTimeId.js.map +1 -0
- package/lib/commonjs/dates/datetime/parseDateTimeId.js +29 -0
- package/lib/commonjs/dates/datetime/parseDateTimeId.js.map +1 -0
- package/lib/commonjs/dates/display/formatDateForDisplay.js +28 -0
- package/lib/commonjs/dates/display/formatDateForDisplay.js.map +1 -0
- package/lib/commonjs/dates/display/formatDateRangeForDisplay.js +25 -0
- package/lib/commonjs/dates/display/formatDateRangeForDisplay.js.map +1 -0
- package/lib/commonjs/dates/display/formatDateTimeForDisplay.js +34 -0
- package/lib/commonjs/dates/display/formatDateTimeForDisplay.js.map +1 -0
- package/lib/commonjs/dates/display/formatMonthForDisplay.js +33 -0
- package/lib/commonjs/dates/display/formatMonthForDisplay.js.map +1 -0
- package/lib/commonjs/dates/index.js +367 -0
- package/lib/commonjs/dates/index.js.map +1 -0
- package/lib/commonjs/dates/internal/brand.js +19 -0
- package/lib/commonjs/dates/internal/brand.js.map +1 -0
- package/lib/commonjs/dates/internal/calendarHelpers.js +22 -0
- package/lib/commonjs/dates/internal/calendarHelpers.js.map +1 -0
- package/lib/commonjs/dates/internal/clampHelpers.js +20 -0
- package/lib/commonjs/dates/internal/clampHelpers.js.map +1 -0
- package/lib/commonjs/dates/internal/dateIdToNativeDate.js +20 -0
- package/lib/commonjs/dates/internal/dateIdToNativeDate.js.map +1 -0
- package/lib/commonjs/dates/internal/intlCache.js +52 -0
- package/lib/commonjs/dates/internal/intlCache.js.map +1 -0
- package/lib/commonjs/dates/internal/intlCopy.js +72 -0
- package/lib/commonjs/dates/internal/intlCopy.js.map +1 -0
- package/lib/commonjs/dates/internal/segmentBuilders.js +98 -0
- package/lib/commonjs/dates/internal/segmentBuilders.js.map +1 -0
- package/lib/commonjs/dates/labels/dateComponentLabels.js +57 -0
- package/lib/commonjs/dates/labels/dateComponentLabels.js.map +1 -0
- package/lib/commonjs/dates/ranges/compareDateIds.js +26 -0
- package/lib/commonjs/dates/ranges/compareDateIds.js.map +1 -0
- package/lib/commonjs/dates/ranges/compareMonthIds.js +31 -0
- package/lib/commonjs/dates/ranges/compareMonthIds.js.map +1 -0
- package/lib/commonjs/dates/ranges/dateRangeAroundDay.js +25 -0
- package/lib/commonjs/dates/ranges/dateRangeAroundDay.js.map +1 -0
- package/lib/commonjs/dates/ranges/dateRangeFromLastNDays.js +28 -0
- package/lib/commonjs/dates/ranges/dateRangeFromLastNDays.js.map +1 -0
- package/lib/commonjs/dates/ranges/eachDateIdInRange.js +29 -0
- package/lib/commonjs/dates/ranges/eachDateIdInRange.js.map +1 -0
- package/lib/commonjs/dates/ranges/normalizeDateRange.js +23 -0
- package/lib/commonjs/dates/ranges/normalizeDateRange.js.map +1 -0
- package/lib/commonjs/dates/segments/applyDateSegmentChange.js +77 -0
- package/lib/commonjs/dates/segments/applyDateSegmentChange.js.map +1 -0
- package/lib/commonjs/dates/segments/formatDateSegment.js +19 -0
- package/lib/commonjs/dates/segments/formatDateSegment.js.map +1 -0
- package/lib/commonjs/dates/segments/getDateFieldSegments.js +44 -0
- package/lib/commonjs/dates/segments/getDateFieldSegments.js.map +1 -0
- package/lib/commonjs/dates/segments/getDateTimeFieldSegments.js +150 -0
- package/lib/commonjs/dates/segments/getDateTimeFieldSegments.js.map +1 -0
- package/lib/commonjs/dates/segments/getDateTimeSegmentVisibility.js +15 -0
- package/lib/commonjs/dates/segments/getDateTimeSegmentVisibility.js.map +1 -0
- package/lib/commonjs/dates/segments/getEmptyDateSegmentText.js +17 -0
- package/lib/commonjs/dates/segments/getEmptyDateSegmentText.js.map +1 -0
- package/lib/commonjs/dates/segments/parseDateSegment.js +26 -0
- package/lib/commonjs/dates/segments/parseDateSegment.js.map +1 -0
- package/lib/commonjs/dates/types.js +2 -0
- package/lib/commonjs/dates/types.js.map +1 -0
- package/lib/commonjs/dates/wire/clampDateParts.js +26 -0
- package/lib/commonjs/dates/wire/clampDateParts.js.map +1 -0
- package/lib/commonjs/dates/wire/clampMonthParts.js +23 -0
- package/lib/commonjs/dates/wire/clampMonthParts.js.map +1 -0
- package/lib/commonjs/dates/wire/dateId.js +50 -0
- package/lib/commonjs/dates/wire/dateId.js.map +1 -0
- package/lib/commonjs/dates/wire/formatDateId.js +25 -0
- package/lib/commonjs/dates/wire/formatDateId.js.map +1 -0
- package/lib/commonjs/dates/wire/formatMonthId.js +21 -0
- package/lib/commonjs/dates/wire/formatMonthId.js.map +1 -0
- package/lib/commonjs/dates/wire/isValidDateId.js +27 -0
- package/lib/commonjs/dates/wire/isValidDateId.js.map +1 -0
- package/lib/commonjs/dates/wire/isValidDateParts.js +18 -0
- package/lib/commonjs/dates/wire/isValidDateParts.js.map +1 -0
- package/lib/commonjs/dates/wire/isValidMonthId.js +27 -0
- package/lib/commonjs/dates/wire/isValidMonthId.js.map +1 -0
- package/lib/commonjs/dates/wire/isValidMonthParts.js +16 -0
- package/lib/commonjs/dates/wire/isValidMonthParts.js.map +1 -0
- package/lib/commonjs/dates/wire/monthId.js +47 -0
- package/lib/commonjs/dates/wire/monthId.js.map +1 -0
- package/lib/commonjs/dates/wire/parseDateId.js +29 -0
- package/lib/commonjs/dates/wire/parseDateId.js.map +1 -0
- package/lib/commonjs/dates/wire/parseMonthId.js +28 -0
- package/lib/commonjs/dates/wire/parseMonthId.js.map +1 -0
- package/lib/commonjs/dates/wire/toMonthId.js +22 -0
- package/lib/commonjs/dates/wire/toMonthId.js.map +1 -0
- package/lib/commonjs/dates/wire/todayDateId.js +17 -0
- package/lib/commonjs/dates/wire/todayDateId.js.map +1 -0
- package/lib/commonjs/dates/wire/todayMonthId.js +17 -0
- package/lib/commonjs/dates/wire/todayMonthId.js.map +1 -0
- package/lib/commonjs/formatNumber.js +50 -0
- package/lib/commonjs/formatNumber.js.map +1 -0
- package/lib/commonjs/index.js +326 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/types.js +2 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/commonjs/utils.js +33 -0
- package/lib/commonjs/utils.js.map +1 -0
- package/lib/module/dates/calendar/formatCalendarMonthYear.js +24 -0
- package/lib/module/dates/calendar/formatCalendarMonthYear.js.map +1 -0
- package/lib/module/dates/calendar/formatDateTimeListDateRow.js +36 -0
- package/lib/module/dates/calendar/formatDateTimeListDateRow.js.map +1 -0
- package/lib/module/dates/calendar/formatMonthCalendarMonth.js +24 -0
- package/lib/module/dates/calendar/formatMonthCalendarMonth.js.map +1 -0
- package/lib/module/dates/calendar/formatMonthCalendarYear.js +12 -0
- package/lib/module/dates/calendar/formatMonthCalendarYear.js.map +1 -0
- package/lib/module/dates/calendar/getCalendarWeekdayLabels.js +19 -0
- package/lib/module/dates/calendar/getCalendarWeekdayLabels.js.map +1 -0
- package/lib/module/dates/datetime/clampDateTimeId.js +24 -0
- package/lib/module/dates/datetime/clampDateTimeId.js.map +1 -0
- package/lib/module/dates/datetime/compareDateTimeIds.js +24 -0
- package/lib/module/dates/datetime/compareDateTimeIds.js.map +1 -0
- package/lib/module/dates/datetime/dateTimeId.js +35 -0
- package/lib/module/dates/datetime/dateTimeId.js.map +1 -0
- package/lib/module/dates/datetime/formatDateTimeId.js +23 -0
- package/lib/module/dates/datetime/formatDateTimeId.js.map +1 -0
- package/lib/module/dates/datetime/formatDateTimeListHour.js +17 -0
- package/lib/module/dates/datetime/formatDateTimeListHour.js.map +1 -0
- package/lib/module/dates/datetime/formatDateTimeListMinute.js +12 -0
- package/lib/module/dates/datetime/formatDateTimeListMinute.js.map +1 -0
- package/lib/module/dates/datetime/formatDateTimeListPeriod.js +13 -0
- package/lib/module/dates/datetime/formatDateTimeListPeriod.js.map +1 -0
- package/lib/module/dates/datetime/isLocaleHour12.js +26 -0
- package/lib/module/dates/datetime/isLocaleHour12.js.map +1 -0
- package/lib/module/dates/datetime/isValidDateTimeId.js +19 -0
- package/lib/module/dates/datetime/isValidDateTimeId.js.map +1 -0
- package/lib/module/dates/datetime/nowDateTimeId.js +54 -0
- package/lib/module/dates/datetime/nowDateTimeId.js.map +1 -0
- package/lib/module/dates/datetime/parseDateTimeId.js +26 -0
- package/lib/module/dates/datetime/parseDateTimeId.js.map +1 -0
- package/lib/module/dates/display/formatDateForDisplay.js +24 -0
- package/lib/module/dates/display/formatDateForDisplay.js.map +1 -0
- package/lib/module/dates/display/formatDateRangeForDisplay.js +22 -0
- package/lib/module/dates/display/formatDateRangeForDisplay.js.map +1 -0
- package/lib/module/dates/display/formatDateTimeForDisplay.js +30 -0
- package/lib/module/dates/display/formatDateTimeForDisplay.js.map +1 -0
- package/lib/module/dates/display/formatMonthForDisplay.js +29 -0
- package/lib/module/dates/display/formatMonthForDisplay.js.map +1 -0
- package/lib/module/dates/index.js +59 -0
- package/lib/module/dates/index.js.map +1 -0
- package/lib/module/dates/internal/brand.js +12 -0
- package/lib/module/dates/internal/brand.js.map +1 -0
- package/lib/module/dates/internal/calendarHelpers.js +19 -0
- package/lib/module/dates/internal/calendarHelpers.js.map +1 -0
- package/lib/module/dates/internal/clampHelpers.js +14 -0
- package/lib/module/dates/internal/clampHelpers.js.map +1 -0
- package/lib/module/dates/internal/dateIdToNativeDate.js +16 -0
- package/lib/module/dates/internal/dateIdToNativeDate.js.map +1 -0
- package/lib/module/dates/internal/intlCache.js +47 -0
- package/lib/module/dates/internal/intlCache.js.map +1 -0
- package/lib/module/dates/internal/intlCopy.js +66 -0
- package/lib/module/dates/internal/intlCopy.js.map +1 -0
- package/lib/module/dates/internal/segmentBuilders.js +91 -0
- package/lib/module/dates/internal/segmentBuilders.js.map +1 -0
- package/lib/module/dates/labels/dateComponentLabels.js +50 -0
- package/lib/module/dates/labels/dateComponentLabels.js.map +1 -0
- package/lib/module/dates/ranges/compareDateIds.js +22 -0
- package/lib/module/dates/ranges/compareDateIds.js.map +1 -0
- package/lib/module/dates/ranges/compareMonthIds.js +27 -0
- package/lib/module/dates/ranges/compareMonthIds.js.map +1 -0
- package/lib/module/dates/ranges/dateRangeAroundDay.js +21 -0
- package/lib/module/dates/ranges/dateRangeAroundDay.js.map +1 -0
- package/lib/module/dates/ranges/dateRangeFromLastNDays.js +24 -0
- package/lib/module/dates/ranges/dateRangeFromLastNDays.js.map +1 -0
- package/lib/module/dates/ranges/eachDateIdInRange.js +26 -0
- package/lib/module/dates/ranges/eachDateIdInRange.js.map +1 -0
- package/lib/module/dates/ranges/normalizeDateRange.js +20 -0
- package/lib/module/dates/ranges/normalizeDateRange.js.map +1 -0
- package/lib/module/dates/segments/applyDateSegmentChange.js +73 -0
- package/lib/module/dates/segments/applyDateSegmentChange.js.map +1 -0
- package/lib/module/dates/segments/formatDateSegment.js +15 -0
- package/lib/module/dates/segments/formatDateSegment.js.map +1 -0
- package/lib/module/dates/segments/getDateFieldSegments.js +40 -0
- package/lib/module/dates/segments/getDateFieldSegments.js.map +1 -0
- package/lib/module/dates/segments/getDateTimeFieldSegments.js +147 -0
- package/lib/module/dates/segments/getDateTimeFieldSegments.js.map +1 -0
- package/lib/module/dates/segments/getDateTimeSegmentVisibility.js +11 -0
- package/lib/module/dates/segments/getDateTimeSegmentVisibility.js.map +1 -0
- package/lib/module/dates/segments/getEmptyDateSegmentText.js +13 -0
- package/lib/module/dates/segments/getEmptyDateSegmentText.js.map +1 -0
- package/lib/module/dates/segments/parseDateSegment.js +22 -0
- package/lib/module/dates/segments/parseDateSegment.js.map +1 -0
- package/lib/module/dates/types.js +2 -0
- package/lib/module/dates/types.js.map +1 -0
- package/lib/module/dates/wire/clampDateParts.js +22 -0
- package/lib/module/dates/wire/clampDateParts.js.map +1 -0
- package/lib/module/dates/wire/clampMonthParts.js +19 -0
- package/lib/module/dates/wire/clampMonthParts.js.map +1 -0
- package/lib/module/dates/wire/dateId.js +47 -0
- package/lib/module/dates/wire/dateId.js.map +1 -0
- package/lib/module/dates/wire/formatDateId.js +22 -0
- package/lib/module/dates/wire/formatDateId.js.map +1 -0
- package/lib/module/dates/wire/formatMonthId.js +17 -0
- package/lib/module/dates/wire/formatMonthId.js.map +1 -0
- package/lib/module/dates/wire/isValidDateId.js +23 -0
- package/lib/module/dates/wire/isValidDateId.js.map +1 -0
- package/lib/module/dates/wire/isValidDateParts.js +14 -0
- package/lib/module/dates/wire/isValidDateParts.js.map +1 -0
- package/lib/module/dates/wire/isValidMonthId.js +23 -0
- package/lib/module/dates/wire/isValidMonthId.js.map +1 -0
- package/lib/module/dates/wire/isValidMonthParts.js +12 -0
- package/lib/module/dates/wire/isValidMonthParts.js.map +1 -0
- package/lib/module/dates/wire/monthId.js +44 -0
- package/lib/module/dates/wire/monthId.js.map +1 -0
- package/lib/module/dates/wire/parseDateId.js +26 -0
- package/lib/module/dates/wire/parseDateId.js.map +1 -0
- package/lib/module/dates/wire/parseMonthId.js +25 -0
- package/lib/module/dates/wire/parseMonthId.js.map +1 -0
- package/lib/module/dates/wire/toMonthId.js +18 -0
- package/lib/module/dates/wire/toMonthId.js.map +1 -0
- package/lib/module/dates/wire/todayDateId.js +13 -0
- package/lib/module/dates/wire/todayDateId.js.map +1 -0
- package/lib/module/dates/wire/todayMonthId.js +13 -0
- package/lib/module/dates/wire/todayMonthId.js.map +1 -0
- package/lib/module/formatNumber.js +46 -0
- package/lib/module/formatNumber.js.map +1 -0
- package/lib/module/index.js +17 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/utils.js +29 -0
- package/lib/module/utils.js.map +1 -0
- package/lib/typescript/dates/calendar/formatCalendarMonthYear.d.ts +12 -0
- package/lib/typescript/dates/calendar/formatCalendarMonthYear.d.ts.map +1 -0
- package/lib/typescript/dates/calendar/formatDateTimeListDateRow.d.ts +13 -0
- package/lib/typescript/dates/calendar/formatDateTimeListDateRow.d.ts.map +1 -0
- package/lib/typescript/dates/calendar/formatMonthCalendarMonth.d.ts +13 -0
- package/lib/typescript/dates/calendar/formatMonthCalendarMonth.d.ts.map +1 -0
- package/lib/typescript/dates/calendar/formatMonthCalendarYear.d.ts +8 -0
- package/lib/typescript/dates/calendar/formatMonthCalendarYear.d.ts.map +1 -0
- package/lib/typescript/dates/calendar/getCalendarWeekdayLabels.d.ts +12 -0
- package/lib/typescript/dates/calendar/getCalendarWeekdayLabels.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/clampDateTimeId.d.ts +16 -0
- package/lib/typescript/dates/datetime/clampDateTimeId.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/compareDateTimeIds.d.ts +13 -0
- package/lib/typescript/dates/datetime/compareDateTimeIds.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/dateTimeId.d.ts +18 -0
- package/lib/typescript/dates/datetime/dateTimeId.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/formatDateTimeId.d.ts +12 -0
- package/lib/typescript/dates/datetime/formatDateTimeId.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/formatDateTimeListHour.d.ts +11 -0
- package/lib/typescript/dates/datetime/formatDateTimeListHour.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/formatDateTimeListMinute.d.ts +8 -0
- package/lib/typescript/dates/datetime/formatDateTimeListMinute.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/formatDateTimeListPeriod.d.ts +9 -0
- package/lib/typescript/dates/datetime/formatDateTimeListPeriod.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/isLocaleHour12.d.ts +12 -0
- package/lib/typescript/dates/datetime/isLocaleHour12.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/isValidDateTimeId.d.ts +9 -0
- package/lib/typescript/dates/datetime/isValidDateTimeId.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/nowDateTimeId.d.ts +14 -0
- package/lib/typescript/dates/datetime/nowDateTimeId.d.ts.map +1 -0
- package/lib/typescript/dates/datetime/parseDateTimeId.d.ts +9 -0
- package/lib/typescript/dates/datetime/parseDateTimeId.d.ts.map +1 -0
- package/lib/typescript/dates/display/formatDateForDisplay.d.ts +13 -0
- package/lib/typescript/dates/display/formatDateForDisplay.d.ts.map +1 -0
- package/lib/typescript/dates/display/formatDateRangeForDisplay.d.ts +16 -0
- package/lib/typescript/dates/display/formatDateRangeForDisplay.d.ts.map +1 -0
- package/lib/typescript/dates/display/formatDateTimeForDisplay.d.ts +13 -0
- package/lib/typescript/dates/display/formatDateTimeForDisplay.d.ts.map +1 -0
- package/lib/typescript/dates/display/formatMonthForDisplay.d.ts +13 -0
- package/lib/typescript/dates/display/formatMonthForDisplay.d.ts.map +1 -0
- package/lib/typescript/dates/index.d.ts +58 -0
- package/lib/typescript/dates/index.d.ts.map +1 -0
- package/lib/typescript/dates/internal/brand.d.ts +11 -0
- package/lib/typescript/dates/internal/brand.d.ts.map +1 -0
- package/lib/typescript/dates/internal/calendarHelpers.d.ts +8 -0
- package/lib/typescript/dates/internal/calendarHelpers.d.ts.map +1 -0
- package/lib/typescript/dates/internal/clampHelpers.d.ts +5 -0
- package/lib/typescript/dates/internal/clampHelpers.d.ts.map +1 -0
- package/lib/typescript/dates/internal/dateIdToNativeDate.d.ts +12 -0
- package/lib/typescript/dates/internal/dateIdToNativeDate.d.ts.map +1 -0
- package/lib/typescript/dates/internal/intlCache.d.ts +12 -0
- package/lib/typescript/dates/internal/intlCache.d.ts.map +1 -0
- package/lib/typescript/dates/internal/intlCopy.d.ts +10 -0
- package/lib/typescript/dates/internal/intlCopy.d.ts.map +1 -0
- package/lib/typescript/dates/internal/segmentBuilders.d.ts +12 -0
- package/lib/typescript/dates/internal/segmentBuilders.d.ts.map +1 -0
- package/lib/typescript/dates/labels/dateComponentLabels.d.ts +31 -0
- package/lib/typescript/dates/labels/dateComponentLabels.d.ts.map +1 -0
- package/lib/typescript/dates/ranges/compareDateIds.d.ts +10 -0
- package/lib/typescript/dates/ranges/compareDateIds.d.ts.map +1 -0
- package/lib/typescript/dates/ranges/compareMonthIds.d.ts +10 -0
- package/lib/typescript/dates/ranges/compareMonthIds.d.ts.map +1 -0
- package/lib/typescript/dates/ranges/dateRangeAroundDay.d.ts +14 -0
- package/lib/typescript/dates/ranges/dateRangeAroundDay.d.ts.map +1 -0
- package/lib/typescript/dates/ranges/dateRangeFromLastNDays.d.ts +16 -0
- package/lib/typescript/dates/ranges/dateRangeFromLastNDays.d.ts.map +1 -0
- package/lib/typescript/dates/ranges/eachDateIdInRange.d.ts +10 -0
- package/lib/typescript/dates/ranges/eachDateIdInRange.d.ts.map +1 -0
- package/lib/typescript/dates/ranges/normalizeDateRange.d.ts +15 -0
- package/lib/typescript/dates/ranges/normalizeDateRange.d.ts.map +1 -0
- package/lib/typescript/dates/segments/applyDateSegmentChange.d.ts +21 -0
- package/lib/typescript/dates/segments/applyDateSegmentChange.d.ts.map +1 -0
- package/lib/typescript/dates/segments/formatDateSegment.d.ts +13 -0
- package/lib/typescript/dates/segments/formatDateSegment.d.ts.map +1 -0
- package/lib/typescript/dates/segments/getDateFieldSegments.d.ts +13 -0
- package/lib/typescript/dates/segments/getDateFieldSegments.d.ts.map +1 -0
- package/lib/typescript/dates/segments/getDateTimeFieldSegments.d.ts +14 -0
- package/lib/typescript/dates/segments/getDateTimeFieldSegments.d.ts.map +1 -0
- package/lib/typescript/dates/segments/getDateTimeSegmentVisibility.d.ts +8 -0
- package/lib/typescript/dates/segments/getDateTimeSegmentVisibility.d.ts.map +1 -0
- package/lib/typescript/dates/segments/getEmptyDateSegmentText.d.ts +9 -0
- package/lib/typescript/dates/segments/getEmptyDateSegmentText.d.ts.map +1 -0
- package/lib/typescript/dates/segments/parseDateSegment.d.ts +13 -0
- package/lib/typescript/dates/segments/parseDateSegment.d.ts.map +1 -0
- package/lib/typescript/dates/types.d.ts +66 -0
- package/lib/typescript/dates/types.d.ts.map +1 -0
- package/lib/typescript/dates/wire/clampDateParts.d.ts +12 -0
- package/lib/typescript/dates/wire/clampDateParts.d.ts.map +1 -0
- package/lib/typescript/dates/wire/clampMonthParts.d.ts +12 -0
- package/lib/typescript/dates/wire/clampMonthParts.d.ts.map +1 -0
- package/lib/typescript/dates/wire/dateId.d.ts +24 -0
- package/lib/typescript/dates/wire/dateId.d.ts.map +1 -0
- package/lib/typescript/dates/wire/formatDateId.d.ts +12 -0
- package/lib/typescript/dates/wire/formatDateId.d.ts.map +1 -0
- package/lib/typescript/dates/wire/formatMonthId.d.ts +12 -0
- package/lib/typescript/dates/wire/formatMonthId.d.ts.map +1 -0
- package/lib/typescript/dates/wire/isValidDateId.d.ts +13 -0
- package/lib/typescript/dates/wire/isValidDateId.d.ts.map +1 -0
- package/lib/typescript/dates/wire/isValidDateParts.d.ts +9 -0
- package/lib/typescript/dates/wire/isValidDateParts.d.ts.map +1 -0
- package/lib/typescript/dates/wire/isValidMonthId.d.ts +13 -0
- package/lib/typescript/dates/wire/isValidMonthId.d.ts.map +1 -0
- package/lib/typescript/dates/wire/isValidMonthParts.d.ts +9 -0
- package/lib/typescript/dates/wire/isValidMonthParts.d.ts.map +1 -0
- package/lib/typescript/dates/wire/monthId.d.ts +22 -0
- package/lib/typescript/dates/wire/monthId.d.ts.map +1 -0
- package/lib/typescript/dates/wire/parseDateId.d.ts +12 -0
- package/lib/typescript/dates/wire/parseDateId.d.ts.map +1 -0
- package/lib/typescript/dates/wire/parseMonthId.d.ts +12 -0
- package/lib/typescript/dates/wire/parseMonthId.d.ts.map +1 -0
- package/lib/typescript/dates/wire/toMonthId.d.ts +12 -0
- package/lib/typescript/dates/wire/toMonthId.d.ts.map +1 -0
- package/lib/typescript/dates/wire/todayDateId.d.ts +8 -0
- package/lib/typescript/dates/wire/todayDateId.d.ts.map +1 -0
- package/lib/typescript/dates/wire/todayMonthId.d.ts +8 -0
- package/lib/typescript/dates/wire/todayMonthId.d.ts.map +1 -0
- package/lib/typescript/formatNumber.d.ts +19 -0
- package/lib/typescript/formatNumber.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +5 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +2 -0
- package/lib/typescript/types.d.ts.map +1 -0
- package/lib/typescript/utils.d.ts +10 -0
- package/lib/typescript/utils.d.ts.map +1 -0
- package/package.json +50 -0
- package/src/__tests__/applyDateSegmentChange.test.ts +26 -0
- package/src/__tests__/calendarFormatters.test.ts +35 -0
- package/src/__tests__/clampDateParts.test.ts +16 -0
- package/src/__tests__/compareDateIds.test.ts +7 -0
- package/src/__tests__/compareMonthIds.test.ts +19 -0
- package/src/__tests__/dateComponentLabels.test.ts +25 -0
- package/src/__tests__/dateRangeAroundDay.test.ts +10 -0
- package/src/__tests__/dateRangeFromLastNDays.test.ts +8 -0
- package/src/__tests__/dateSegmentHelpers.test.ts +24 -0
- package/src/__tests__/datetimeHelpers.test.ts +65 -0
- package/src/__tests__/displayFormatters.test.ts +34 -0
- package/src/__tests__/eachDateIdInRange.test.ts +11 -0
- package/src/__tests__/formatCalendarMonthYear.test.ts +9 -0
- package/src/__tests__/formatDateForDisplay.test.ts +11 -0
- package/src/__tests__/formatDateId.test.ts +15 -0
- package/src/__tests__/formatMonthId.test.ts +7 -0
- package/src/__tests__/formatNumber.test.ts +35 -0
- package/src/__tests__/getDateFieldSegments.test.ts +35 -0
- package/src/__tests__/getDateTimeFieldSegments.test.ts +140 -0
- package/src/__tests__/getDateTimeSegmentVisibility.test.ts +12 -0
- package/src/__tests__/intlCopy.test.ts +64 -0
- package/src/__tests__/isValidDateId.test.ts +8 -0
- package/src/__tests__/isValidMonthId.test.ts +8 -0
- package/src/__tests__/normalizeDateRange.test.ts +10 -0
- package/src/__tests__/toMonthId.test.ts +7 -0
- package/src/__tests__/todayDateId.test.ts +7 -0
- package/src/__tests__/wireConstructors.test.ts +74 -0
- package/src/dates/calendar/formatCalendarMonthYear.ts +21 -0
- package/src/dates/calendar/formatDateTimeListDateRow.ts +41 -0
- package/src/dates/calendar/formatMonthCalendarMonth.ts +21 -0
- package/src/dates/calendar/formatMonthCalendarYear.ts +9 -0
- package/src/dates/calendar/getCalendarWeekdayLabels.ts +23 -0
- package/src/dates/datetime/clampDateTimeId.ts +25 -0
- package/src/dates/datetime/compareDateTimeIds.ts +23 -0
- package/src/dates/datetime/dateTimeId.ts +36 -0
- package/src/dates/datetime/formatDateTimeId.ts +35 -0
- package/src/dates/datetime/formatDateTimeListHour.ts +14 -0
- package/src/dates/datetime/formatDateTimeListMinute.ts +9 -0
- package/src/dates/datetime/formatDateTimeListPeriod.ts +12 -0
- package/src/dates/datetime/isLocaleHour12.ts +23 -0
- package/src/dates/datetime/isValidDateTimeId.ts +18 -0
- package/src/dates/datetime/nowDateTimeId.ts +53 -0
- package/src/dates/datetime/parseDateTimeId.ts +24 -0
- package/src/dates/display/formatDateForDisplay.ts +21 -0
- package/src/dates/display/formatDateRangeForDisplay.ts +23 -0
- package/src/dates/display/formatDateTimeForDisplay.ts +37 -0
- package/src/dates/display/formatMonthForDisplay.ts +26 -0
- package/src/dates/index.ts +86 -0
- package/src/dates/internal/brand.ts +11 -0
- package/src/dates/internal/calendarHelpers.ts +18 -0
- package/src/dates/internal/clampHelpers.ts +15 -0
- package/src/dates/internal/dateIdToNativeDate.ts +15 -0
- package/src/dates/internal/intlCache.ts +40 -0
- package/src/dates/internal/intlCopy.ts +75 -0
- package/src/dates/internal/segmentBuilders.ts +94 -0
- package/src/dates/labels/dateComponentLabels.ts +79 -0
- package/src/dates/ranges/compareDateIds.ts +21 -0
- package/src/dates/ranges/compareMonthIds.ts +26 -0
- package/src/dates/ranges/dateRangeAroundDay.ts +24 -0
- package/src/dates/ranges/dateRangeFromLastNDays.ts +26 -0
- package/src/dates/ranges/eachDateIdInRange.ts +21 -0
- package/src/dates/ranges/normalizeDateRange.ts +18 -0
- package/src/dates/segments/applyDateSegmentChange.ts +57 -0
- package/src/dates/segments/formatDateSegment.ts +18 -0
- package/src/dates/segments/getDateFieldSegments.ts +45 -0
- package/src/dates/segments/getDateTimeFieldSegments.ts +126 -0
- package/src/dates/segments/getDateTimeSegmentVisibility.ts +14 -0
- package/src/dates/segments/getEmptyDateSegmentText.ts +12 -0
- package/src/dates/segments/parseDateSegment.ts +25 -0
- package/src/dates/types.ts +80 -0
- package/src/dates/wire/clampDateParts.ts +17 -0
- package/src/dates/wire/clampMonthParts.ts +15 -0
- package/src/dates/wire/dateId.ts +44 -0
- package/src/dates/wire/formatDateId.ts +20 -0
- package/src/dates/wire/formatMonthId.ts +16 -0
- package/src/dates/wire/isValidDateId.ts +22 -0
- package/src/dates/wire/isValidDateParts.ts +17 -0
- package/src/dates/wire/isValidMonthId.ts +22 -0
- package/src/dates/wire/isValidMonthParts.ts +11 -0
- package/src/dates/wire/monthId.ts +42 -0
- package/src/dates/wire/parseDateId.ts +20 -0
- package/src/dates/wire/parseMonthId.ts +20 -0
- package/src/dates/wire/toMonthId.ts +17 -0
- package/src/dates/wire/todayDateId.ts +12 -0
- package/src/dates/wire/todayMonthId.ts +12 -0
- package/src/formatNumber.ts +56 -0
- package/src/index.ts +82 -0
- package/src/types.ts +1 -0
- package/src/utils.ts +29 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { addDays, format, subDays } from 'date-fns';
|
|
2
|
+
import { asDateId } from '../internal/brand';
|
|
3
|
+
import { dateIdToNativeDate } from '../internal/dateIdToNativeDate';
|
|
4
|
+
import type { DateId } from '../types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Builds an inclusive window of dates around an anchor (default: today).
|
|
8
|
+
*
|
|
9
|
+
* @param daysBefore - Number of days before the anchor (inclusive).
|
|
10
|
+
* @param daysAfter - Number of days after the anchor (inclusive).
|
|
11
|
+
* @param anchorDate - Optional anchor wire date; defaults to today.
|
|
12
|
+
* @returns Start and end wire date ids for the window.
|
|
13
|
+
*/
|
|
14
|
+
export function dateRangeAroundDay(
|
|
15
|
+
daysBefore: number,
|
|
16
|
+
daysAfter: number,
|
|
17
|
+
anchorDate?: DateId,
|
|
18
|
+
): { startId: DateId; endId: DateId } {
|
|
19
|
+
const anchor = anchorDate ? dateIdToNativeDate(anchorDate) : new Date();
|
|
20
|
+
return {
|
|
21
|
+
startId: asDateId(format(subDays(anchor, daysBefore), 'yyyy-MM-dd')),
|
|
22
|
+
endId: asDateId(format(addDays(anchor, daysAfter), 'yyyy-MM-dd')),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { format, subDays } from 'date-fns';
|
|
2
|
+
import { asDateId } from '../internal/brand';
|
|
3
|
+
import { dateIdToNativeDate } from '../internal/dateIdToNativeDate';
|
|
4
|
+
import type { DateId } from '../types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Builds an inclusive "last N days" preset ending on `endDate` (default: today).
|
|
8
|
+
*
|
|
9
|
+
* @param days - Number of calendar days in the range (inclusive of end).
|
|
10
|
+
* @param endDate - Optional end wire date; defaults to today.
|
|
11
|
+
* @returns Normalized start/end wire date ids.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* dateRangeFromLastNDays(30) // { startId, endId } spanning 30 calendar days
|
|
15
|
+
*/
|
|
16
|
+
export function dateRangeFromLastNDays(
|
|
17
|
+
days: number,
|
|
18
|
+
endDate?: DateId,
|
|
19
|
+
): { startId: DateId; endId: DateId } {
|
|
20
|
+
const end = endDate ? dateIdToNativeDate(endDate) : new Date();
|
|
21
|
+
const start = subDays(end, days - 1);
|
|
22
|
+
return {
|
|
23
|
+
startId: asDateId(format(start, 'yyyy-MM-dd')),
|
|
24
|
+
endId: asDateId(format(end, 'yyyy-MM-dd')),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { eachDayOfInterval, format } from 'date-fns';
|
|
2
|
+
import { asDateId } from '../internal/brand';
|
|
3
|
+
import { dateIdToNativeDate } from '../internal/dateIdToNativeDate';
|
|
4
|
+
import type { DateId } from '../types';
|
|
5
|
+
import { normalizeDateRange } from './normalizeDateRange';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Returns an inclusive list of every `DateId` between start and end (order-normalized).
|
|
9
|
+
*
|
|
10
|
+
* @param startId - Range start wire date.
|
|
11
|
+
* @param endId - Range end wire date.
|
|
12
|
+
* @returns Array of wire `DateId` strings for each day in the range.
|
|
13
|
+
*/
|
|
14
|
+
export function eachDateIdInRange(startId: DateId, endId: DateId): DateId[] {
|
|
15
|
+
const normalized = normalizeDateRange({ startId, endId });
|
|
16
|
+
const days = eachDayOfInterval({
|
|
17
|
+
start: dateIdToNativeDate(normalized.startId),
|
|
18
|
+
end: dateIdToNativeDate(normalized.endId),
|
|
19
|
+
});
|
|
20
|
+
return days.map((day) => asDateId(format(day, 'yyyy-MM-dd')));
|
|
21
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { DateId } from '../types';
|
|
2
|
+
import { compareDateIds } from './compareDateIds';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Ensures `startId` ≤ `endId` by swapping when the range is inverted.
|
|
6
|
+
*
|
|
7
|
+
* @param range - Start and end wire date ids.
|
|
8
|
+
* @returns Normalized range with `startId` on or before `endId`.
|
|
9
|
+
*/
|
|
10
|
+
export function normalizeDateRange(range: { startId: DateId; endId: DateId }): {
|
|
11
|
+
startId: DateId;
|
|
12
|
+
endId: DateId;
|
|
13
|
+
} {
|
|
14
|
+
if (compareDateIds(range.startId, range.endId) <= 0) {
|
|
15
|
+
return range;
|
|
16
|
+
}
|
|
17
|
+
return { startId: range.endId, endId: range.startId };
|
|
18
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { clampDateParts } from '../wire/clampDateParts';
|
|
2
|
+
import { clampMonthParts } from '../wire/clampMonthParts';
|
|
3
|
+
import type { DateFieldMode, DateParts, DateSegmentType, MonthParts } from '../types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Applies a single segment edit to complete date/month parts, clamping invalid days/months.
|
|
7
|
+
*
|
|
8
|
+
* Prefer this when updating a fully known value. Segmented `DateField` mid-entry uses
|
|
9
|
+
* partial parts internally and does not call this helper.
|
|
10
|
+
*
|
|
11
|
+
* @param current - Current parts, or `null` for defaults.
|
|
12
|
+
* @param segment - Segment type being edited.
|
|
13
|
+
* @param value - New numeric value for the segment.
|
|
14
|
+
* @param options - Field mode (`date` or `month`).
|
|
15
|
+
* @returns Updated parts, or `null` when input cannot be applied.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* applyDateSegmentChange(parseDateId('2026-01-31'), 'month', 2, { mode: 'date' })
|
|
19
|
+
* // → { year: 2026, month: 2, day: 28 }
|
|
20
|
+
*/
|
|
21
|
+
export function applyDateSegmentChange(
|
|
22
|
+
current: DateParts | MonthParts | null,
|
|
23
|
+
segment: DateSegmentType,
|
|
24
|
+
value: number,
|
|
25
|
+
options: { mode: DateFieldMode },
|
|
26
|
+
): DateParts | MonthParts | null {
|
|
27
|
+
if (options.mode === 'month') {
|
|
28
|
+
const base: MonthParts =
|
|
29
|
+
current && 'month' in current && !('day' in current)
|
|
30
|
+
? { year: current.year, month: current.month }
|
|
31
|
+
: { year: new Date().getFullYear(), month: 1 };
|
|
32
|
+
|
|
33
|
+
if (segment === 'month') {
|
|
34
|
+
return clampMonthParts({ ...base, month: value });
|
|
35
|
+
}
|
|
36
|
+
if (segment === 'year') {
|
|
37
|
+
return { ...base, year: value };
|
|
38
|
+
}
|
|
39
|
+
return base;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const base: DateParts =
|
|
43
|
+
current && 'day' in current
|
|
44
|
+
? { year: current.year, month: current.month, day: current.day }
|
|
45
|
+
: { year: new Date().getFullYear(), month: 1, day: 1 };
|
|
46
|
+
|
|
47
|
+
if (segment === 'month') {
|
|
48
|
+
return clampDateParts({ ...base, month: value });
|
|
49
|
+
}
|
|
50
|
+
if (segment === 'day') {
|
|
51
|
+
return clampDateParts({ ...base, day: value });
|
|
52
|
+
}
|
|
53
|
+
if (segment === 'year') {
|
|
54
|
+
return clampDateParts({ ...base, year: value });
|
|
55
|
+
}
|
|
56
|
+
return base;
|
|
57
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { padSegment } from '../internal/segmentBuilders';
|
|
2
|
+
import type { DateSegmentType } from '../types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Formats a numeric segment value for display in a segmented date field.
|
|
6
|
+
*
|
|
7
|
+
* @param type - Segment type (year, month, day, etc.).
|
|
8
|
+
* @param value - Numeric segment value.
|
|
9
|
+
* @param _options - Reserved for future locale-aware formatting.
|
|
10
|
+
* @returns Padded segment text.
|
|
11
|
+
*/
|
|
12
|
+
export function formatDateSegment(
|
|
13
|
+
type: DateSegmentType,
|
|
14
|
+
value: number,
|
|
15
|
+
_options?: { locale?: string },
|
|
16
|
+
): string {
|
|
17
|
+
return padSegment(type, value);
|
|
18
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { asDateId, asMonthId } from '../internal/brand';
|
|
2
|
+
import { buildDateFieldSegments, buildEmptyDateFieldSegments } from '../internal/segmentBuilders';
|
|
3
|
+
import { parseDateId } from '../wire/parseDateId';
|
|
4
|
+
import { parseMonthId } from '../wire/parseMonthId';
|
|
5
|
+
import type { DateFieldMode, DateId, DateSegment, MonthId } from '../types';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Builds ordered editable and literal segments for a date or month field from a wire value.
|
|
9
|
+
*
|
|
10
|
+
* @param value - Wire `DateId` or `MonthId`, or empty for placeholder segments.
|
|
11
|
+
* @param options - Field mode and optional locale.
|
|
12
|
+
* @returns Ordered `DateSegment` array matching locale field order.
|
|
13
|
+
*/
|
|
14
|
+
export function getDateFieldSegments(
|
|
15
|
+
value: DateId | MonthId | null | undefined,
|
|
16
|
+
options: { mode: DateFieldMode; locale?: string },
|
|
17
|
+
): DateSegment[] {
|
|
18
|
+
const locale = options.locale ?? 'en-US';
|
|
19
|
+
|
|
20
|
+
if (!value) {
|
|
21
|
+
return buildEmptyDateFieldSegments(options.mode, locale);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (options.mode === 'month') {
|
|
25
|
+
const parts = parseMonthId(asMonthId(value));
|
|
26
|
+
if (!parts) {
|
|
27
|
+
return buildEmptyDateFieldSegments('month', locale);
|
|
28
|
+
}
|
|
29
|
+
return buildDateFieldSegments(
|
|
30
|
+
{ year: parts.year, month: parts.month, day: 1 },
|
|
31
|
+
'month',
|
|
32
|
+
locale,
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const parts = parseDateId(asDateId(value));
|
|
37
|
+
if (!parts) {
|
|
38
|
+
return buildEmptyDateFieldSegments('date', locale);
|
|
39
|
+
}
|
|
40
|
+
return buildDateFieldSegments(
|
|
41
|
+
{ year: parts.year, month: parts.month, day: parts.day },
|
|
42
|
+
'date',
|
|
43
|
+
locale,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { formatDayPeriodFromHour } from '../internal/intlCopy';
|
|
2
|
+
import { EMPTY_TIME_SEGMENT_TEXT, padSegment } from '../internal/segmentBuilders';
|
|
3
|
+
import { formatDateId } from '../wire/formatDateId';
|
|
4
|
+
import { isLocaleHour12 } from '../datetime/isLocaleHour12';
|
|
5
|
+
import { parseDateTimeId } from '../datetime/parseDateTimeId';
|
|
6
|
+
import type { DateSegment, DateTimeGranularity, DateTimeId } from '../types';
|
|
7
|
+
import { getDateFieldSegments } from './getDateFieldSegments';
|
|
8
|
+
import { getDateTimeSegmentVisibility } from './getDateTimeSegmentVisibility';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Builds ordered segments for a date-time field for the given granularity.
|
|
12
|
+
*
|
|
13
|
+
* @param value - Wire `DateTimeId`, or empty for placeholder segments.
|
|
14
|
+
* @param options - Granularity, locale, and 12/24-hour preference.
|
|
15
|
+
* @returns Ordered `DateSegment` array including date and time parts.
|
|
16
|
+
*/
|
|
17
|
+
export function getDateTimeFieldSegments(
|
|
18
|
+
value: DateTimeId | null | undefined,
|
|
19
|
+
options: { granularity: DateTimeGranularity; locale?: string; hour12?: boolean },
|
|
20
|
+
): DateSegment[] {
|
|
21
|
+
const parts = value ? parseDateTimeId(value) : null;
|
|
22
|
+
const locale = options.locale ?? 'en-US';
|
|
23
|
+
const hour12 = options.hour12 ?? isLocaleHour12(locale);
|
|
24
|
+
const segments: DateSegment[] = getDateFieldSegments(parts ? formatDateId(parts) : undefined, {
|
|
25
|
+
mode: 'date',
|
|
26
|
+
locale: options.locale,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
if (options.granularity === 'day') {
|
|
30
|
+
return segments;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const { showMinute, showSecond } = getDateTimeSegmentVisibility(options.granularity);
|
|
34
|
+
|
|
35
|
+
if (!parts) {
|
|
36
|
+
segments.push({ type: 'literal', text: ' ', isEditable: false });
|
|
37
|
+
segments.push({
|
|
38
|
+
type: 'hour',
|
|
39
|
+
text: hour12 ? EMPTY_TIME_SEGMENT_TEXT.hour : 'HH',
|
|
40
|
+
isEditable: true,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
if (showMinute) {
|
|
44
|
+
segments.push({ type: 'literal', text: ':', isEditable: false });
|
|
45
|
+
segments.push({
|
|
46
|
+
type: 'minute',
|
|
47
|
+
text: EMPTY_TIME_SEGMENT_TEXT.minute,
|
|
48
|
+
isEditable: true,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (showSecond) {
|
|
53
|
+
segments.push({ type: 'literal', text: ':', isEditable: false });
|
|
54
|
+
segments.push({
|
|
55
|
+
type: 'second',
|
|
56
|
+
text: EMPTY_TIME_SEGMENT_TEXT.second,
|
|
57
|
+
isEditable: true,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (hour12) {
|
|
62
|
+
segments.push({ type: 'literal', text: ' ', isEditable: false });
|
|
63
|
+
segments.push({
|
|
64
|
+
type: 'dayPeriod',
|
|
65
|
+
text: EMPTY_TIME_SEGMENT_TEXT.dayPeriod,
|
|
66
|
+
isEditable: true,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return segments;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const hour = parts.hour;
|
|
74
|
+
const minute = parts.minute;
|
|
75
|
+
|
|
76
|
+
segments.push({ type: 'literal', text: ' ', isEditable: false });
|
|
77
|
+
if (hour12) {
|
|
78
|
+
const hour12Value = hour % 12 || 12;
|
|
79
|
+
segments.push({
|
|
80
|
+
type: 'hour',
|
|
81
|
+
text: String(hour12Value),
|
|
82
|
+
value: hour12Value,
|
|
83
|
+
isEditable: true,
|
|
84
|
+
});
|
|
85
|
+
} else {
|
|
86
|
+
segments.push({
|
|
87
|
+
type: 'hour',
|
|
88
|
+
text: padSegment('hour', hour),
|
|
89
|
+
value: hour,
|
|
90
|
+
isEditable: true,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (showMinute) {
|
|
95
|
+
segments.push({ type: 'literal', text: ':', isEditable: false });
|
|
96
|
+
segments.push({
|
|
97
|
+
type: 'minute',
|
|
98
|
+
text: padSegment('minute', minute),
|
|
99
|
+
value: minute,
|
|
100
|
+
isEditable: true,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (showSecond) {
|
|
105
|
+
segments.push({ type: 'literal', text: ':', isEditable: false });
|
|
106
|
+
segments.push({
|
|
107
|
+
type: 'second',
|
|
108
|
+
text: padSegment('second', parts.second ?? 0),
|
|
109
|
+
value: parts.second ?? 0,
|
|
110
|
+
isEditable: true,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (hour12) {
|
|
115
|
+
const isPm = hour >= 12;
|
|
116
|
+
segments.push({ type: 'literal', text: ' ', isEditable: false });
|
|
117
|
+
segments.push({
|
|
118
|
+
type: 'dayPeriod',
|
|
119
|
+
text: formatDayPeriodFromHour(isPm ? 13 : 9, locale),
|
|
120
|
+
value: isPm ? 1 : 0,
|
|
121
|
+
isEditable: true,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return segments;
|
|
126
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DateTimeGranularity } from '../types';
|
|
2
|
+
|
|
3
|
+
/** Which time segments/columns are visible for a given `DateTimeGranularity`. */
|
|
4
|
+
export function getDateTimeSegmentVisibility(granularity: DateTimeGranularity): {
|
|
5
|
+
showTime: boolean;
|
|
6
|
+
showMinute: boolean;
|
|
7
|
+
showSecond: boolean;
|
|
8
|
+
} {
|
|
9
|
+
return {
|
|
10
|
+
showTime: granularity !== 'day',
|
|
11
|
+
showMinute: granularity === 'minute' || granularity === 'second',
|
|
12
|
+
showSecond: granularity === 'second',
|
|
13
|
+
};
|
|
14
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { EMPTY_DATE_SEGMENT_TEXT } from '../internal/segmentBuilders';
|
|
2
|
+
import type { DateSegmentType } from '../types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Returns placeholder text for an empty editable segment (e.g. `MM`, `DD`, `YYYY`).
|
|
6
|
+
*
|
|
7
|
+
* @param type - Segment type.
|
|
8
|
+
* @returns Placeholder string, or `''` for types without a placeholder.
|
|
9
|
+
*/
|
|
10
|
+
export function getEmptyDateSegmentText(type: DateSegmentType): string {
|
|
11
|
+
return EMPTY_DATE_SEGMENT_TEXT[type] ?? '';
|
|
12
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DateSegmentType } from '../types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Parses user-entered segment text into a number, or `null` when not parseable.
|
|
5
|
+
*
|
|
6
|
+
* @param type - Segment type being edited.
|
|
7
|
+
* @param text - Raw segment text from the field.
|
|
8
|
+
* @param _options - Reserved for future locale-aware parsing.
|
|
9
|
+
* @returns Parsed number, or `null` for empty or non-numeric input.
|
|
10
|
+
*/
|
|
11
|
+
export function parseDateSegment(
|
|
12
|
+
type: DateSegmentType,
|
|
13
|
+
text: string,
|
|
14
|
+
_options?: { locale?: string },
|
|
15
|
+
): number | null {
|
|
16
|
+
const trimmed = text.trim();
|
|
17
|
+
if (!trimmed || type === 'literal' || type === 'dayPeriod') {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const parsed = Number(trimmed);
|
|
21
|
+
if (Number.isNaN(parsed)) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
return parsed;
|
|
25
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared option / parts types for date wire and display helpers.
|
|
3
|
+
*
|
|
4
|
+
* Wire brands: `DateId` (`YYYY-MM-DD`), `MonthId` (`YYYY-MM-01`), `DateTimeId` (local ISO-like).
|
|
5
|
+
*
|
|
6
|
+
* These are branded string types: a bare `string` no longer assigns to a `DateId`
|
|
7
|
+
* (etc.) prop. Produce values through the validating smart constructors
|
|
8
|
+
* (`dateId(...)`, `monthId(...)`, `dateTimeId(...)`) or the wire producers
|
|
9
|
+
* (`todayDateId()`, `parseDateId(...)`, `formatDateId(...)`, …), all exported from
|
|
10
|
+
* `@cdx-ui/formatters`. The brand is a compile-time-only tag — at runtime these are
|
|
11
|
+
* ordinary strings safe to serialize, store, and send over the wire.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** Wire date id (`YYYY-MM-DD`). Construct via `dateId(...)`, never a bare string. */
|
|
15
|
+
export type DateId = string & { readonly __brand: 'DateId' };
|
|
16
|
+
/** Wire month id (`YYYY-MM-01`). Construct via `monthId(...)`, never a bare string. */
|
|
17
|
+
export type MonthId = string & { readonly __brand: 'MonthId' };
|
|
18
|
+
/** Wire date-time id (local ISO-like, e.g. `YYYY-MM-DDTHH:mm`). Construct via `dateTimeId(...)`. */
|
|
19
|
+
export type DateTimeId = string & { readonly __brand: 'DateTimeId' };
|
|
20
|
+
|
|
21
|
+
export interface DateParts {
|
|
22
|
+
year: number;
|
|
23
|
+
month: number;
|
|
24
|
+
day: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface MonthParts {
|
|
28
|
+
year: number;
|
|
29
|
+
month: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface TimeParts {
|
|
33
|
+
hour: number;
|
|
34
|
+
minute: number;
|
|
35
|
+
second?: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface DateTimeParts extends DateParts, TimeParts {}
|
|
39
|
+
|
|
40
|
+
export type DateFieldMode = 'date' | 'month';
|
|
41
|
+
|
|
42
|
+
export type DateTimeGranularity = 'day' | 'hour' | 'minute' | 'second';
|
|
43
|
+
|
|
44
|
+
export type DateSegmentType =
|
|
45
|
+
| 'era'
|
|
46
|
+
| 'year'
|
|
47
|
+
| 'month'
|
|
48
|
+
| 'day'
|
|
49
|
+
| 'hour'
|
|
50
|
+
| 'minute'
|
|
51
|
+
| 'second'
|
|
52
|
+
| 'dayPeriod'
|
|
53
|
+
| 'literal';
|
|
54
|
+
|
|
55
|
+
export interface DateSegment {
|
|
56
|
+
type: DateSegmentType;
|
|
57
|
+
text: string;
|
|
58
|
+
value?: number;
|
|
59
|
+
isEditable: boolean;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface DateFormatOptions {
|
|
63
|
+
locale?: string;
|
|
64
|
+
timeZone?: string;
|
|
65
|
+
calendar?: string;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface FormatDateDisplayOptions extends DateFormatOptions {
|
|
69
|
+
dateStyle?: 'short' | 'medium' | 'long';
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface FormatDateTimeDisplayOptions extends DateFormatOptions {
|
|
73
|
+
dateStyle?: 'short' | 'medium' | 'long';
|
|
74
|
+
timeStyle?: 'short' | 'medium';
|
|
75
|
+
granularity?: DateTimeGranularity;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface DateRangeDisplayOptions extends FormatDateDisplayOptions {
|
|
79
|
+
rangeSeparator?: string;
|
|
80
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { clampDay, clampMonth } from '../internal/clampHelpers';
|
|
2
|
+
import type { DateParts } from '../types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Clamps date parts so month is 1–12 and day fits the month length (no `Date` rollover).
|
|
6
|
+
*
|
|
7
|
+
* @param parts - Year, month, and day values to clamp.
|
|
8
|
+
* @returns Clamped `DateParts` with a valid calendar day for the given month.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* clampDateParts({ year: 2026, month: 2, day: 31 }) // { year: 2026, month: 2, day: 28 }
|
|
12
|
+
*/
|
|
13
|
+
export function clampDateParts(parts: DateParts): DateParts {
|
|
14
|
+
const month = clampMonth(parts.month);
|
|
15
|
+
const day = clampDay(parts.year, month, parts.day);
|
|
16
|
+
return { year: parts.year, month, day };
|
|
17
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { clampMonth } from '../internal/clampHelpers';
|
|
2
|
+
import type { MonthParts } from '../types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Clamps month parts so month is between 1 and 12.
|
|
6
|
+
*
|
|
7
|
+
* @param parts - Year and month values to clamp.
|
|
8
|
+
* @returns Clamped `MonthParts`.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* clampMonthParts({ year: 2026, month: 13 }) // { year: 2026, month: 12 }
|
|
12
|
+
*/
|
|
13
|
+
export function clampMonthParts(parts: MonthParts): MonthParts {
|
|
14
|
+
return { year: parts.year, month: clampMonth(parts.month) };
|
|
15
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { asDateId } from '../internal/brand';
|
|
2
|
+
import type { DateId } from '../types';
|
|
3
|
+
import { formatDateId } from './formatDateId';
|
|
4
|
+
import { isValidDateId } from './isValidDateId';
|
|
5
|
+
import { isValidDateParts } from './isValidDateParts';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Validating smart constructor for a wire {@link DateId} (`YYYY-MM-DD`).
|
|
9
|
+
*
|
|
10
|
+
* Accepts either a wire string or numeric parts. Throws `RangeError` on input
|
|
11
|
+
* that is not a real calendar date — use this at the boundary where you first
|
|
12
|
+
* introduce a date value so a bad id never enters your form state.
|
|
13
|
+
*
|
|
14
|
+
* @param iso - A wire date string (`YYYY-MM-DD`).
|
|
15
|
+
* @returns The branded `DateId`.
|
|
16
|
+
* @throws RangeError when the string is not a valid `DateId`.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* dateId('2026-08-07'); // DateId
|
|
20
|
+
* dateId(2026, 8, 7); // DateId
|
|
21
|
+
*/
|
|
22
|
+
export function dateId(iso: string): DateId;
|
|
23
|
+
/**
|
|
24
|
+
* @param year - Full year (e.g. `2026`).
|
|
25
|
+
* @param month - Month `1`–`12`.
|
|
26
|
+
* @param day - Day of month `1`–`31`.
|
|
27
|
+
*/
|
|
28
|
+
export function dateId(year: number, month: number, day: number): DateId;
|
|
29
|
+
export function dateId(yearOrIso: string | number, month?: number, day?: number): DateId {
|
|
30
|
+
if (typeof yearOrIso === 'string') {
|
|
31
|
+
if (!isValidDateId(yearOrIso)) {
|
|
32
|
+
throw new RangeError(
|
|
33
|
+
`Invalid DateId: "${yearOrIso}". Expected a real calendar date as "YYYY-MM-DD".`,
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
return yearOrIso;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const parts = { year: yearOrIso, month: month ?? NaN, day: day ?? NaN };
|
|
40
|
+
if (!isValidDateParts(parts)) {
|
|
41
|
+
throw new RangeError(`Invalid DateId parts: ${JSON.stringify(parts)}.`);
|
|
42
|
+
}
|
|
43
|
+
return asDateId(formatDateId(parts));
|
|
44
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { asDateId } from '../internal/brand';
|
|
2
|
+
import type { DateId, DateParts } from '../types';
|
|
3
|
+
import { clampDateParts } from './clampDateParts';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Builds a wire `DateId`, clamping day to the month length (no `Date` rollover).
|
|
7
|
+
*
|
|
8
|
+
* @param parts - Year, month, and day values.
|
|
9
|
+
* @returns Wire `DateId` string (`YYYY-MM-DD`).
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* formatDateId({ year: 2026, month: 7, day: 28 }) // '2026-07-28'
|
|
13
|
+
*/
|
|
14
|
+
export function formatDateId(parts: DateParts): DateId {
|
|
15
|
+
const clamped = clampDateParts(parts);
|
|
16
|
+
const year = String(clamped.year).padStart(4, '0');
|
|
17
|
+
const month = String(clamped.month).padStart(2, '0');
|
|
18
|
+
const day = String(clamped.day).padStart(2, '0');
|
|
19
|
+
return asDateId(`${year}-${month}-${day}`);
|
|
20
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { format } from 'date-fns';
|
|
2
|
+
import { asMonthId } from '../internal/brand';
|
|
3
|
+
import type { MonthId, MonthParts } from '../types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Builds a wire `MonthId` (`YYYY-MM-01`).
|
|
7
|
+
*
|
|
8
|
+
* @param parts - Year and month values.
|
|
9
|
+
* @returns Wire `MonthId` string.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* formatMonthId({ year: 2026, month: 7 }) // '2026-07-01'
|
|
13
|
+
*/
|
|
14
|
+
export function formatMonthId(parts: MonthParts): MonthId {
|
|
15
|
+
return asMonthId(format(new Date(parts.year, parts.month - 1, 1), 'yyyy-MM-dd'));
|
|
16
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { format, isValid, parse } from 'date-fns';
|
|
2
|
+
import type { DateId } from '../types';
|
|
3
|
+
|
|
4
|
+
const DATE_ID_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Type guard for wire `DateId` strings (`YYYY-MM-DD`).
|
|
8
|
+
*
|
|
9
|
+
* @param dateId - Candidate wire date string.
|
|
10
|
+
* @returns `true` when `dateId` is a valid `DateId`.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* isValidDateId('2026-07-28') // true
|
|
14
|
+
* isValidDateId('07/28/2026') // false
|
|
15
|
+
*/
|
|
16
|
+
export function isValidDateId(dateId: string): dateId is DateId {
|
|
17
|
+
if (!DATE_ID_PATTERN.test(dateId)) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const parsed = parse(dateId, 'yyyy-MM-dd', new Date());
|
|
21
|
+
return isValid(parsed) && format(parsed, 'yyyy-MM-dd') === dateId;
|
|
22
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { partsToDate } from '../internal/clampHelpers';
|
|
2
|
+
import type { DateParts } from '../types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Returns whether the given parts form a valid calendar date.
|
|
6
|
+
*
|
|
7
|
+
* @param parts - Year, month, and day values to validate.
|
|
8
|
+
* @returns `true` when the parts match a real calendar date.
|
|
9
|
+
*/
|
|
10
|
+
export function isValidDateParts(parts: DateParts): boolean {
|
|
11
|
+
const date = partsToDate(parts);
|
|
12
|
+
return (
|
|
13
|
+
date.getFullYear() === parts.year &&
|
|
14
|
+
date.getMonth() === parts.month - 1 &&
|
|
15
|
+
date.getDate() === parts.day
|
|
16
|
+
);
|
|
17
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { format, isValid, parse } from 'date-fns';
|
|
2
|
+
import type { MonthId } from '../types';
|
|
3
|
+
|
|
4
|
+
const MONTH_ID_PATTERN = /^\d{4}-\d{2}-01$/;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Type guard for wire `MonthId` strings (`YYYY-MM-01`).
|
|
8
|
+
*
|
|
9
|
+
* @param monthId - Candidate wire month string.
|
|
10
|
+
* @returns `true` when `monthId` is a valid `MonthId`.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* isValidMonthId('2026-07-01') // true
|
|
14
|
+
* isValidMonthId('2026-07-15') // false
|
|
15
|
+
*/
|
|
16
|
+
export function isValidMonthId(monthId: string): monthId is MonthId {
|
|
17
|
+
if (!MONTH_ID_PATTERN.test(monthId)) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const parsed = parse(monthId, 'yyyy-MM-dd', new Date());
|
|
21
|
+
return isValid(parsed) && format(parsed, 'yyyy-MM-dd') === monthId;
|
|
22
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { MonthParts } from '../types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns whether the given parts form a valid month (1–12).
|
|
5
|
+
*
|
|
6
|
+
* @param parts - Year and month values to validate.
|
|
7
|
+
* @returns `true` when month is between 1 and 12.
|
|
8
|
+
*/
|
|
9
|
+
export function isValidMonthParts(parts: MonthParts): boolean {
|
|
10
|
+
return parts.month >= 1 && parts.month <= 12;
|
|
11
|
+
}
|