@full-ui/headless-calendar 7.0.0-beta.8 → 7.1.0-alpha.0

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.
Files changed (3) hide show
  1. package/index.d.ts +49 -26
  2. package/index.js +258 -54
  3. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -119,13 +119,10 @@ declare function expandZonedMarker(dateInfo: ZonedMarker, calendarSystem: Calend
119
119
  interface VerboseFormattingData {
120
120
  date: ExpandedZonedMarker;
121
121
  start: ExpandedZonedMarker;
122
- end?: ExpandedZonedMarker;
122
+ end?: ExpandedZonedMarker | null;
123
123
  timeZone: string;
124
124
  localeCodes: string[];
125
- defaultSeparator: string;
126
125
  }
127
- declare function createVerboseFormattingArg(start: ZonedMarker, end: ZonedMarker, context: DateFormattingContext, betterDefaultSeparator?: string): VerboseFormattingData;
128
- type CmdFormatterFunc = (cmd: string, data: VerboseFormattingData) => string | Intl.DateTimeFormatPart[];
129
126
  interface DateFormattingContext {
130
127
  timeZone: string;
131
128
  locale: Locale;
@@ -133,12 +130,19 @@ interface DateFormattingContext {
133
130
  computeWeekNumber: (d: DateMarker) => number;
134
131
  weekText: string;
135
132
  weekTextShort: string;
136
- cmdFormatter?: CmdFormatterFunc;
137
- defaultSeparator: string;
133
+ cmdFormatter?: CmdDateFormatterFunc;
138
134
  }
135
+ declare function createVerboseFormattingArg(start: ZonedMarker, end: ZonedMarker | null, context: DateFormattingContext): VerboseFormattingData;
136
+ type DateTimeFormatPartWithWeek = Omit<Intl.DateTimeFormatPart, 'type'> & {
137
+ type: Intl.DateTimeFormatPart['type'] | 'week';
138
+ };
139
+ type DateTimeRangeFormatPartWithWeek = Omit<Intl.DateTimeRangeFormatPart, 'type'> & {
140
+ type: Intl.DateTimeRangeFormatPart['type'] | 'week';
141
+ };
142
+ type CmdDateFormatterFunc = (cmd: string, data: VerboseFormattingData) => string | DateTimeFormatPartWithWeek[];
139
143
  interface DateFormatter {
140
- format(date: ZonedMarker, context: DateFormattingContext): [string, Intl.DateTimeFormatPart[]];
141
- formatRange(start: ZonedMarker, end: ZonedMarker, context: DateFormattingContext, betterDefaultSeparator?: string): string;
144
+ formatToParts(date: ZonedMarker, context: DateFormattingContext): DateTimeFormatPartWithWeek[];
145
+ formatRangeToParts(start: ZonedMarker, end: ZonedMarker, context: DateFormattingContext): DateTimeRangeFormatPartWithWeek[];
142
146
  }
143
147
 
144
148
  type WeekNumberCalculation = 'local' | 'ISO' | ((m: Date) => number);
@@ -150,8 +154,7 @@ interface DateEnvSettings {
150
154
  firstDay?: number;
151
155
  weekText?: string;
152
156
  weekTextShort?: string;
153
- cmdFormatter?: CmdFormatterFunc;
154
- defaultSeparator?: string;
157
+ cmdFormatter?: CmdDateFormatterFunc;
155
158
  }
156
159
  type DateInput = Date | string | number | number[];
157
160
  interface DateMarkerMeta {
@@ -167,8 +170,7 @@ declare class DateEnv {
167
170
  weekNumberFunc: any;
168
171
  weekText: string;
169
172
  weekTextShort: string;
170
- cmdFormatter?: CmdFormatterFunc;
171
- defaultSeparator: string;
173
+ cmdFormatter?: CmdDateFormatterFunc;
172
174
  constructor(settings: DateEnvSettings);
173
175
  createMarker(input: DateInput): DateMarker;
174
176
  createNowMarker(): DateMarker;
@@ -196,11 +198,10 @@ declare class DateEnv {
196
198
  startOfMonth(m: DateMarker): DateMarker;
197
199
  startOfWeek(m: DateMarker): DateMarker;
198
200
  computeWeekNumber(marker: DateMarker): number;
199
- format(marker: DateMarker, formatter: DateFormatter): [string, Intl.DateTimeFormatPart[]];
200
- formatRange(start: DateMarker, end: DateMarker, formatter: DateFormatter, dateOptions?: {
201
+ formatToParts(marker: DateMarker, formatter: DateFormatter): DateTimeFormatPartWithWeek[];
202
+ formatRangeToParts(start: DateMarker, end: DateMarker, formatter: DateFormatter, dateOptions?: {
201
203
  isEndExclusive?: boolean;
202
- defaultSeparator?: string;
203
- }): string;
204
+ }): DateTimeRangeFormatPartWithWeek[];
204
205
  formatIso(marker: DateMarker, extraOptions?: any): string;
205
206
  timestampToMarker(ms: number): Date;
206
207
  offsetForMarker(m: DateMarker): number;
@@ -228,19 +229,41 @@ declare function rangeContainsRange(outerRange: OpenDateRange, innerRange: OpenD
228
229
  declare function rangeContainsMarker(range: OpenDateRange, date: DateMarker | number): boolean;
229
230
  declare function constrainMarkerToRange(date: DateMarker, range: DateRange): DateMarker;
230
231
 
231
- declare class CmdFormatter implements DateFormatter {
232
+ interface NativeDateFormatterOptions extends Intl.DateTimeFormatOptions {
233
+ week?: 'long' | 'short' | 'narrow' | 'numeric';
234
+ meridiem?: 'lowercase' | 'short' | 'narrow' | boolean;
235
+ omitZeroMinute?: boolean;
236
+ omitCommas?: boolean;
237
+ forceCommas?: boolean;
238
+ omitTrailing?: boolean;
239
+ weekdayJustify?: 'start' | 'end';
240
+ }
241
+ declare class NativeDateFormatter implements DateFormatter {
242
+ private standardOptions;
243
+ private extendedOptions;
244
+ private weekOnly;
245
+ private timeZoneOnly;
246
+ private cachedContext;
247
+ private cachedFormats;
248
+ constructor(options?: NativeDateFormatterOptions);
249
+ formatToParts(date: ZonedMarker, context: DateFormattingContext): DateTimeFormatPartWithWeek[];
250
+ formatRangeToParts(start: ZonedMarker, end: ZonedMarker, context: DateFormattingContext): DateTimeRangeFormatPartWithWeek[];
251
+ private getFormats;
252
+ }
253
+
254
+ declare class CmdDateFormatter implements DateFormatter {
232
255
  cmdStr: string;
233
256
  constructor(cmdStr: string);
234
- format(date: ZonedMarker, context: DateFormattingContext, betterDefaultSeparator?: string): [string, Intl.DateTimeFormatPart[]];
235
- formatRange(start: ZonedMarker, end: ZonedMarker, context: DateFormattingContext, betterDefaultSeparator?: string): string;
257
+ formatToParts(date: ZonedMarker, context: DateFormattingContext): DateTimeFormatPartWithWeek[];
258
+ formatRangeToParts(start: ZonedMarker, end: ZonedMarker, context: DateFormattingContext): DateTimeRangeFormatPartWithWeek[];
236
259
  }
237
260
 
238
- type FuncFormatterFunc = (data: VerboseFormattingData) => string;
239
- declare class FuncFormatter implements DateFormatter {
240
- func: FuncFormatterFunc;
241
- constructor(func: FuncFormatterFunc);
242
- format(date: ZonedMarker, context: DateFormattingContext, betterDefaultSeparator?: string): [string, Intl.DateTimeFormatPart[]];
243
- formatRange(start: ZonedMarker, end: ZonedMarker, context: DateFormattingContext, betterDefaultSeparator?: string): string;
261
+ type FuncDateFormatterFunc = (info: VerboseFormattingData) => string;
262
+ declare class FuncDateFormatter implements DateFormatter {
263
+ func: FuncDateFormatterFunc;
264
+ constructor(func: FuncDateFormatterFunc);
265
+ formatToParts(date: ZonedMarker, context: DateFormattingContext): DateTimeFormatPartWithWeek[];
266
+ formatRangeToParts(start: ZonedMarker, end: ZonedMarker, context: DateFormattingContext): DateTimeRangeFormatPartWithWeek[];
244
267
  }
245
268
 
246
269
  declare function buildIsoString(marker: DateMarker, timeZoneOffset?: number, stripZeroTime?: boolean): string;
@@ -262,4 +285,4 @@ declare function isInt(n: any): boolean;
262
285
  declare function trimEnd(s: string): string;
263
286
  declare function padStart(val: any, len: any): string;
264
287
 
265
- export { CalendarSystem, CmdFormatter, CmdFormatterFunc, DateEnv, DateEnvSettings, DateFormatter, DateFormattingContext, DateInput, DateMarker, DateMarkerMeta, DateRange, DateRangeInput, Duration, DurationInput, DurationObjectInput, ExpandedZonedMarker, FuncFormatter, FuncFormatterFunc, Locale, LocaleCodeArg, OpenDateRange, VerboseFormattingData, WeekNumberCalculation, ZonedMarker, addDays, addDurations, addMs, addWeeks, arrayToLocalDate, arrayToUtcDate, asCleanDays, asRoughDays, asRoughHours, asRoughMinutes, asRoughMonths, asRoughMs, asRoughSeconds, asRoughYears, buildIsoString, constrainMarkerToRange, createCalendarSystem, createDuration, createVerboseFormattingArg, dateToLocalArray, dateToUtcArray, diffDayAndTime, diffDays, diffHours, diffMinutes, diffSeconds, diffWeeks, diffWholeDays, diffWholeWeeks, durationsEqual, expandZonedMarker, formatDayString, formatIsoMonthStr, formatIsoTimeString, formatTimeZoneOffset, greatestDurationDenominator, intersectRanges, invertRanges, isInt, isValidDate, joinDateTimeFormatParts, multiplyDuration, padStart, parse as parseMarker, parseRange, rangeContainsMarker, rangeContainsRange, rangesEqual, rangesIntersect, registerCalendarSystem, startOfDay, startOfHour, startOfMinute, startOfSecond, subtractDurations, timeAsMs, trimEnd, weekOfYear, wholeDivideDurations };
288
+ export { CalendarSystem, CmdDateFormatter, CmdDateFormatterFunc, DateEnv, DateEnvSettings, DateFormatter, DateFormattingContext, DateInput, DateMarker, DateMarkerMeta, DateRange, DateRangeInput, DateTimeFormatPartWithWeek, DateTimeRangeFormatPartWithWeek, Duration, DurationInput, DurationObjectInput, ExpandedZonedMarker, FuncDateFormatter, FuncDateFormatterFunc, Locale, LocaleCodeArg, NativeDateFormatter, NativeDateFormatterOptions, OpenDateRange, VerboseFormattingData, WeekNumberCalculation, ZonedMarker, addDays, addDurations, addMs, addWeeks, arrayToLocalDate, arrayToUtcDate, asCleanDays, asRoughDays, asRoughHours, asRoughMinutes, asRoughMonths, asRoughMs, asRoughSeconds, asRoughYears, buildIsoString, constrainMarkerToRange, createCalendarSystem, createDuration, createVerboseFormattingArg, dateToLocalArray, dateToUtcArray, diffDayAndTime, diffDays, diffHours, diffMinutes, diffSeconds, diffWeeks, diffWholeDays, diffWholeWeeks, durationsEqual, expandZonedMarker, formatDayString, formatIsoMonthStr, formatIsoTimeString, formatTimeZoneOffset, greatestDurationDenominator, intersectRanges, invertRanges, isInt, isValidDate, joinDateTimeFormatParts, multiplyDuration, padStart, parse as parseMarker, parseRange, rangeContainsMarker, rangeContainsRange, rangesEqual, rangesIntersect, registerCalendarSystem, startOfDay, startOfHour, startOfMinute, startOfSecond, subtractDurations, timeAsMs, trimEnd, weekOfYear, wholeDivideDurations };
package/index.js CHANGED
@@ -306,7 +306,7 @@ function expandZonedMarker(dateInfo, calendarSystem) {
306
306
  };
307
307
  }
308
308
 
309
- function createVerboseFormattingArg(start, end, context, betterDefaultSeparator) {
309
+ function createVerboseFormattingArg(start, end, context) {
310
310
  let startInfo = expandZonedMarker(start, context.calendarSystem);
311
311
  let endInfo = end ? expandZonedMarker(end, context.calendarSystem) : null;
312
312
  return {
@@ -315,7 +315,6 @@ function createVerboseFormattingArg(start, end, context, betterDefaultSeparator)
315
315
  end: endInfo,
316
316
  timeZone: context.timeZone,
317
317
  localeCodes: context.locale.codes,
318
- defaultSeparator: betterDefaultSeparator || context.defaultSeparator,
319
318
  };
320
319
  }
321
320
 
@@ -500,27 +499,22 @@ function buildIsoString(marker, timeZoneOffset, stripZeroTime = false) {
500
499
  if (stripZeroTime) {
501
500
  s = s.replace('T00:00:00Z', '');
502
501
  }
503
- if (s.length > 10) { // time part wasn't stripped, can add timezone info
502
+ if (s.length > 10) {
504
503
  if (timeZoneOffset == null) {
505
504
  s = s.replace('Z', '');
506
505
  }
507
506
  else if (timeZoneOffset !== 0) {
508
507
  s = s.replace('Z', formatTimeZoneOffset(timeZoneOffset, true));
509
508
  }
510
- // otherwise, its UTC-0 and we want to keep the Z
511
509
  }
512
510
  return s;
513
511
  }
514
- // formats the date, but with no time part
515
- // TODO: somehow merge with buildIsoString and stripZeroTime
516
- // TODO: rename. omit "string"
517
512
  function formatDayString(marker) {
518
513
  return marker.toISOString().replace(/T.*$/, '');
519
514
  }
520
515
  function formatIsoMonthStr(marker) {
521
516
  return marker.toISOString().match(/^\d{4}-\d{2}/)[0];
522
517
  }
523
- // TODO: use Date::toISOString and use everything after the T?
524
518
  function formatIsoTimeString(marker) {
525
519
  return padStart(marker.getUTCHours(), 2) + ':' +
526
520
  padStart(marker.getUTCMinutes(), 2) + ':' +
@@ -567,7 +561,6 @@ function parse(str) {
567
561
 
568
562
  class DateEnv {
569
563
  constructor(settings) {
570
- var _a;
571
564
  this.timeZone = settings.timeZone;
572
565
  this.calendarSystem = createCalendarSystem(settings.calendarSystem);
573
566
  this.locale = settings.locale;
@@ -584,9 +577,8 @@ class DateEnv {
584
577
  this.weekNumberFunc = settings.weekNumberCalculation;
585
578
  }
586
579
  this.weekText = settings.weekText;
587
- this.weekTextShort = (_a = settings.weekTextShort) !== null && _a !== void 0 ? _a : settings.weekText;
580
+ this.weekTextShort = settings.weekTextShort ?? settings.weekText;
588
581
  this.cmdFormatter = settings.cmdFormatter;
589
- this.defaultSeparator = settings.defaultSeparator;
590
582
  }
591
583
  // Creating / Parsing
592
584
  createMarker(input) {
@@ -794,25 +786,23 @@ class DateEnv {
794
786
  }
795
787
  return weekOfYear(marker, this.weekDow, this.weekDoy);
796
788
  }
797
- // TODO: choke on timeZoneName: long
798
- format(marker, formatter) {
799
- return formatter.format({
789
+ formatToParts(marker, formatter) {
790
+ return formatter.formatToParts({
800
791
  marker,
801
792
  timeZoneOffset: this.offsetForMarker(marker),
802
793
  }, this);
803
794
  }
804
- // Unlike format(), returns plain string!
805
- formatRange(start, end, formatter, dateOptions = {}) {
795
+ formatRangeToParts(start, end, formatter, dateOptions = {}) {
806
796
  if (dateOptions.isEndExclusive) {
807
797
  end = addMs(end, -1);
808
798
  }
809
- return formatter.formatRange({
799
+ return formatter.formatRangeToParts({
810
800
  marker: start,
811
801
  timeZoneOffset: this.offsetForMarker(start),
812
802
  }, {
813
803
  marker: end,
814
804
  timeZoneOffset: this.offsetForMarker(end),
815
- }, this, dateOptions.defaultSeparator);
805
+ }, this);
816
806
  }
817
807
  /*
818
808
  DUMB: the omitTime arg is dumb. if we omit the time, we want to omit the timezone offset. and if we do that,
@@ -858,54 +848,268 @@ class DateEnv {
858
848
  }
859
849
  }
860
850
 
861
- /*
862
- TODO: fix the terminology of "formatter" vs "formatting func"
863
- */
864
- /*
865
- At the time of instantiation, this object does not know which cmd-formatting system it will use.
866
- It receives this at the time of formatting, as a setting.
867
- */
868
- class CmdFormatter {
851
+ const EXTENDED_SETTINGS = new Set([
852
+ 'week',
853
+ 'meridiem',
854
+ 'omitZeroMinute',
855
+ 'omitCommas',
856
+ 'forceCommas',
857
+ 'omitTrailing',
858
+ 'weekdayJustify',
859
+ ]);
860
+ const MERIDIEM_RE = /([ap])\.?m\.?/i;
861
+ const COMMA_RE = /,/g;
862
+ const LTR_RE = /\u200e/g; // control character
863
+ const TRAILING_RE = /[\s.,]+$/;
864
+ const WHITESPACE_ONLY_RE = /^\s+$/;
865
+ class NativeDateFormatter {
866
+ constructor(options) {
867
+ const standardOptions = {};
868
+ const extendedOptions = {};
869
+ for (const name in options) {
870
+ if (EXTENDED_SETTINGS.has(name)) {
871
+ extendedOptions[name] = options[name];
872
+ }
873
+ else {
874
+ standardOptions[name] = options[name];
875
+ }
876
+ }
877
+ if (standardOptions.timeZoneName === 'long') {
878
+ standardOptions.timeZoneName = 'short';
879
+ }
880
+ this.timeZoneOnly = Object.keys(standardOptions).length === 1 &&
881
+ standardOptions.timeZoneName === 'short';
882
+ this.weekOnly = Boolean(!Object.keys(standardOptions).length && extendedOptions.week);
883
+ if (!this.timeZoneOnly) {
884
+ if (standardOptions.timeZoneName) {
885
+ if (!standardOptions.hour) {
886
+ standardOptions.hour = '2-digit';
887
+ }
888
+ if (!standardOptions.minute) {
889
+ standardOptions.minute = '2-digit';
890
+ }
891
+ }
892
+ if (extendedOptions.omitZeroMinute &&
893
+ (standardOptions.second || standardOptions.fractionalSecondDigits)) {
894
+ delete extendedOptions.omitZeroMinute;
895
+ }
896
+ standardOptions.timeZone = 'UTC';
897
+ }
898
+ this.standardOptions = standardOptions;
899
+ this.extendedOptions = extendedOptions;
900
+ }
901
+ formatToParts(date, context) {
902
+ const { standardOptions, extendedOptions } = this;
903
+ if (this.timeZoneOnly) {
904
+ return [{
905
+ type: 'timeZoneName',
906
+ value: formatTimeZoneOffset(date.timeZoneOffset),
907
+ }];
908
+ }
909
+ if (this.weekOnly) {
910
+ return formatWeekNumberParts(context.computeWeekNumber(date.marker), context.weekText, context.weekTextShort, context.locale, extendedOptions.week);
911
+ }
912
+ const { normalFormat, zeroFormat } = this.getFormats(context);
913
+ const format = (zeroFormat && !date.marker.getUTCMinutes())
914
+ ? zeroFormat
915
+ : normalFormat;
916
+ const parts = format.formatToParts(date.marker);
917
+ return postProcessParts(parts, date, standardOptions, extendedOptions);
918
+ }
919
+ formatRangeToParts(start, end, context) {
920
+ const { standardOptions, extendedOptions } = this;
921
+ if (this.timeZoneOnly || this.weekOnly) {
922
+ return this.formatToParts(start, context).map((part) => {
923
+ return {
924
+ source: part.type === 'literal' ? 'shared' : 'startRange',
925
+ ...part,
926
+ };
927
+ });
928
+ }
929
+ const { normalFormat, zeroFormat } = this.getFormats(context);
930
+ const format = (zeroFormat && !start.marker.getUTCMinutes() && !end.marker.getUTCMinutes())
931
+ ? zeroFormat
932
+ : normalFormat;
933
+ const parts = format.formatRangeToParts(start.marker, end.marker);
934
+ return postProcessRangeParts(parts, start, end, standardOptions, extendedOptions);
935
+ }
936
+ getFormats(context) {
937
+ if (this.cachedContext !== context) {
938
+ const { standardOptions, extendedOptions } = this;
939
+ const { codes } = context.locale;
940
+ const normalFormat = new Intl.DateTimeFormat(codes, standardOptions);
941
+ let zeroFormat;
942
+ if (extendedOptions.omitZeroMinute) {
943
+ const zeroProps = { ...standardOptions };
944
+ delete zeroProps.minute;
945
+ zeroFormat = new Intl.DateTimeFormat(codes, zeroProps);
946
+ }
947
+ this.cachedContext = context;
948
+ this.cachedFormats = { normalFormat, zeroFormat };
949
+ }
950
+ return this.cachedFormats;
951
+ }
952
+ }
953
+ function processPartsLoop(parts, extendedOptions, getTzValue) {
954
+ let anyTzInjected = false;
955
+ let priorLiteral;
956
+ for (const part of parts) {
957
+ const isLiteral = part.type === 'literal';
958
+ if (isLiteral || part.type === 'dayPeriod') {
959
+ let s = part.value;
960
+ s = s.replace(LTR_RE, '');
961
+ if (extendedOptions.omitCommas) {
962
+ s = s.replace(COMMA_RE, '');
963
+ }
964
+ if (!isLiteral) {
965
+ const { meridiem } = extendedOptions;
966
+ if (meridiem === false) {
967
+ s = s.replace(MERIDIEM_RE, '');
968
+ }
969
+ else if (meridiem === 'narrow') {
970
+ s = s.replace(MERIDIEM_RE, (_m0, m1) => m1.toLocaleLowerCase());
971
+ }
972
+ else if (meridiem === 'short') {
973
+ s = s.replace(MERIDIEM_RE, (_m0, m1) => `${m1.toLocaleLowerCase()}m`);
974
+ }
975
+ else if (meridiem === 'lowercase') {
976
+ s = s.replace(MERIDIEM_RE, (m0) => m0.toLocaleLowerCase());
977
+ }
978
+ if (priorLiteral) {
979
+ priorLiteral.value = priorLiteral.value.trimEnd();
980
+ }
981
+ }
982
+ part.value = s;
983
+ }
984
+ else if (part.type === 'timeZoneName') {
985
+ const tzValue = getTzValue(part);
986
+ if (tzValue != null) {
987
+ part.value = tzValue;
988
+ anyTzInjected = true;
989
+ }
990
+ }
991
+ priorLiteral = isLiteral ? part : undefined;
992
+ }
993
+ return { lastLiteral: priorLiteral, anyTzInjected };
994
+ }
995
+ function postProcessParts(parts, date, standardOptions, extendedOptions) {
996
+ const injectableTz = standardOptions.timeZoneName === 'short'
997
+ ? (date.timeZoneOffset == null ? 'UTC' : formatTimeZoneOffset(date.timeZoneOffset))
998
+ : undefined;
999
+ const { lastLiteral, anyTzInjected } = processPartsLoop(parts, extendedOptions, () => injectableTz);
1000
+ if (injectableTz && !anyTzInjected) {
1001
+ if (lastLiteral) {
1002
+ lastLiteral.value += ' ';
1003
+ }
1004
+ else {
1005
+ parts.push({ type: 'literal', value: ' ' });
1006
+ }
1007
+ parts.push({ type: 'timeZoneName', value: injectableTz });
1008
+ }
1009
+ if (extendedOptions.weekdayJustify &&
1010
+ parts.length === 3 &&
1011
+ WHITESPACE_ONLY_RE.test(parts[1].value)) {
1012
+ if (parts[extendedOptions.weekdayJustify === 'start' ? 2 : 0].type === 'weekday') {
1013
+ parts.reverse();
1014
+ }
1015
+ }
1016
+ if (extendedOptions.forceCommas) {
1017
+ for (const part of parts) {
1018
+ if (part.type === 'literal' && WHITESPACE_ONLY_RE.test(part.value)) {
1019
+ part.value = `,${part.value}`;
1020
+ }
1021
+ }
1022
+ }
1023
+ if (extendedOptions.omitTrailing) {
1024
+ stripTrailingLiteral(parts);
1025
+ }
1026
+ return parts.filter((part) => part.value);
1027
+ }
1028
+ function postProcessRangeParts(parts, start, end, standardOptions, extendedOptions) {
1029
+ const injectTz = standardOptions.timeZoneName === 'short';
1030
+ processPartsLoop(parts, extendedOptions, (part) => {
1031
+ if (!injectTz)
1032
+ return undefined;
1033
+ const offset = part.source === 'endRange' ? end.timeZoneOffset : start.timeZoneOffset;
1034
+ return offset == null ? 'UTC' : formatTimeZoneOffset(offset);
1035
+ });
1036
+ if (extendedOptions.forceCommas) {
1037
+ for (const part of parts) {
1038
+ if (part.type === 'literal' && WHITESPACE_ONLY_RE.test(part.value)) {
1039
+ part.value = `,${part.value}`;
1040
+ }
1041
+ }
1042
+ }
1043
+ if (extendedOptions.omitTrailing) {
1044
+ stripTrailingLiteral(parts);
1045
+ }
1046
+ return parts.filter((part) => part.value);
1047
+ }
1048
+ function stripTrailingLiteral(parts) {
1049
+ const lastPart = parts[parts.length - 1];
1050
+ if (lastPart?.type === 'literal') {
1051
+ lastPart.value = lastPart.value.replace(TRAILING_RE, '');
1052
+ if (!lastPart.value) {
1053
+ parts.pop();
1054
+ }
1055
+ }
1056
+ }
1057
+ function formatWeekNumberParts(num, weekText, weekTextShort, locale, display) {
1058
+ const parts = [];
1059
+ if (display === 'long') {
1060
+ parts.push({ type: 'literal', value: weekText });
1061
+ }
1062
+ else if (display === 'short' || display === 'narrow') {
1063
+ parts.push({ type: 'literal', value: weekTextShort });
1064
+ }
1065
+ if (display === 'long' || display === 'short') {
1066
+ parts.push({ type: 'literal', value: ' ' });
1067
+ }
1068
+ parts.push({
1069
+ type: 'week',
1070
+ value: locale.simpleNumberFormat.format(num),
1071
+ });
1072
+ if (locale.options.direction === 'rtl') {
1073
+ parts.reverse();
1074
+ }
1075
+ return parts;
1076
+ }
1077
+
1078
+ class CmdDateFormatter {
869
1079
  constructor(cmdStr) {
870
1080
  this.cmdStr = cmdStr;
871
1081
  }
872
- format(date, context, betterDefaultSeparator) {
873
- const res = context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(date, null, context, betterDefaultSeparator));
874
- // array of parts?
875
- if (typeof res === 'object') {
876
- return [joinDateTimeFormatParts(res), res];
1082
+ formatToParts(date, context) {
1083
+ const res = context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(date, null, context));
1084
+ if (Array.isArray(res)) {
1085
+ return res;
877
1086
  }
878
- // otherwise, just a string
879
- return [res, [{ type: 'literal', value: res }]];
880
- }
881
- // Unlike format(), returns plain string!
882
- formatRange(start, end, context, betterDefaultSeparator) {
883
- const res = context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(start, end, context, betterDefaultSeparator));
884
- // array of parts?
885
- if (typeof res === 'object') {
886
- return joinDateTimeFormatParts(res);
1087
+ return [{ type: 'literal', value: res }];
1088
+ }
1089
+ formatRangeToParts(start, end, context) {
1090
+ const res = context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(start, end, context));
1091
+ if (Array.isArray(res)) {
1092
+ return res.map((part) => ({
1093
+ source: 'shared',
1094
+ ...part,
1095
+ }));
887
1096
  }
888
- // otherwise, just a string
889
- return res;
1097
+ return [{ source: 'shared', type: 'literal', value: res }];
890
1098
  }
891
1099
  }
892
1100
 
893
- class FuncFormatter {
1101
+ class FuncDateFormatter {
894
1102
  constructor(func) {
895
1103
  this.func = func;
896
1104
  }
897
- format(date, context, betterDefaultSeparator) {
898
- const str = this.func(createVerboseFormattingArg(date, null, context, betterDefaultSeparator));
899
- return [
900
- str,
901
- // HACK. In future versions, allow func-formatters to return parts?
902
- [{ type: 'literal', value: str }],
903
- ];
1105
+ formatToParts(date, context) {
1106
+ const str = this.func(createVerboseFormattingArg(date, null, context));
1107
+ return [{ type: 'literal', value: str }];
904
1108
  }
905
- // Unlike format(), returns plain string!
906
- formatRange(start, end, context, betterDefaultSeparator) {
907
- return this.func(createVerboseFormattingArg(start, end, context, betterDefaultSeparator));
1109
+ formatRangeToParts(start, end, context) {
1110
+ const str = this.func(createVerboseFormattingArg(start, end, context));
1111
+ return [{ source: 'shared', type: 'literal', value: str }];
908
1112
  }
909
1113
  }
910
1114
 
911
- export { CmdFormatter, DateEnv, FuncFormatter, addDays, addDurations, addMs, addWeeks, arrayToLocalDate, arrayToUtcDate, asCleanDays, asRoughDays, asRoughHours, asRoughMinutes, asRoughMonths, asRoughMs, asRoughSeconds, asRoughYears, buildIsoString, constrainMarkerToRange, createCalendarSystem, createDuration, createVerboseFormattingArg, dateToLocalArray, dateToUtcArray, diffDayAndTime, diffDays, diffHours, diffMinutes, diffSeconds, diffWeeks, diffWholeDays, diffWholeWeeks, durationsEqual, expandZonedMarker, formatDayString, formatIsoMonthStr, formatIsoTimeString, formatTimeZoneOffset, greatestDurationDenominator, intersectRanges, invertRanges, isInt, isValidDate, joinDateTimeFormatParts, multiplyDuration, padStart, parse as parseMarker, parseRange, rangeContainsMarker, rangeContainsRange, rangesEqual, rangesIntersect, registerCalendarSystem, startOfDay, startOfHour, startOfMinute, startOfSecond, subtractDurations, timeAsMs, trimEnd, weekOfYear, wholeDivideDurations };
1115
+ export { CmdDateFormatter, DateEnv, FuncDateFormatter, NativeDateFormatter, addDays, addDurations, addMs, addWeeks, arrayToLocalDate, arrayToUtcDate, asCleanDays, asRoughDays, asRoughHours, asRoughMinutes, asRoughMonths, asRoughMs, asRoughSeconds, asRoughYears, buildIsoString, constrainMarkerToRange, createCalendarSystem, createDuration, createVerboseFormattingArg, dateToLocalArray, dateToUtcArray, diffDayAndTime, diffDays, diffHours, diffMinutes, diffSeconds, diffWeeks, diffWholeDays, diffWholeWeeks, durationsEqual, expandZonedMarker, formatDayString, formatIsoMonthStr, formatIsoTimeString, formatTimeZoneOffset, greatestDurationDenominator, intersectRanges, invertRanges, isInt, isValidDate, joinDateTimeFormatParts, multiplyDuration, padStart, parse as parseMarker, parseRange, rangeContainsMarker, rangeContainsRange, rangesEqual, rangesIntersect, registerCalendarSystem, startOfDay, startOfHour, startOfMinute, startOfSecond, subtractDurations, timeAsMs, trimEnd, weekOfYear, wholeDivideDurations };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@full-ui/headless-calendar",
3
- "version": "7.0.0-beta.8",
3
+ "version": "7.1.0-alpha.0",
4
4
  "keywords": [
5
5
  "headless",
6
6
  "calendar",