@full-ui/headless-calendar 7.0.0-beta.7 → 7.0.0-rc.1

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 +265 -60
  3. package/package.json +2 -2
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
@@ -1,4 +1,6 @@
1
- import { Temporal } from 'temporal-polyfill';
1
+ import * as ZonedDateTimeFns from 'temporal-polyfill/fns/zoneddatetime';
2
+ import * as PlainDateTimeFns from 'temporal-polyfill/fns/plaindatetime';
3
+ import * as InstantFns from 'temporal-polyfill/fns/instant';
2
4
 
3
5
  // Adding
4
6
  function addWeeks(m, n) {
@@ -304,7 +306,7 @@ function expandZonedMarker(dateInfo, calendarSystem) {
304
306
  };
305
307
  }
306
308
 
307
- function createVerboseFormattingArg(start, end, context, betterDefaultSeparator) {
309
+ function createVerboseFormattingArg(start, end, context) {
308
310
  let startInfo = expandZonedMarker(start, context.calendarSystem);
309
311
  let endInfo = end ? expandZonedMarker(end, context.calendarSystem) : null;
310
312
  return {
@@ -313,7 +315,6 @@ function createVerboseFormattingArg(start, end, context, betterDefaultSeparator)
313
315
  end: endInfo,
314
316
  timeZone: context.timeZone,
315
317
  localeCodes: context.locale.codes,
316
- defaultSeparator: betterDefaultSeparator || context.defaultSeparator,
317
318
  };
318
319
  }
319
320
 
@@ -498,27 +499,22 @@ function buildIsoString(marker, timeZoneOffset, stripZeroTime = false) {
498
499
  if (stripZeroTime) {
499
500
  s = s.replace('T00:00:00Z', '');
500
501
  }
501
- if (s.length > 10) { // time part wasn't stripped, can add timezone info
502
+ if (s.length > 10) {
502
503
  if (timeZoneOffset == null) {
503
504
  s = s.replace('Z', '');
504
505
  }
505
506
  else if (timeZoneOffset !== 0) {
506
507
  s = s.replace('Z', formatTimeZoneOffset(timeZoneOffset, true));
507
508
  }
508
- // otherwise, its UTC-0 and we want to keep the Z
509
509
  }
510
510
  return s;
511
511
  }
512
- // formats the date, but with no time part
513
- // TODO: somehow merge with buildIsoString and stripZeroTime
514
- // TODO: rename. omit "string"
515
512
  function formatDayString(marker) {
516
513
  return marker.toISOString().replace(/T.*$/, '');
517
514
  }
518
515
  function formatIsoMonthStr(marker) {
519
516
  return marker.toISOString().match(/^\d{4}-\d{2}/)[0];
520
517
  }
521
- // TODO: use Date::toISOString and use everything after the T?
522
518
  function formatIsoTimeString(marker) {
523
519
  return padStart(marker.getUTCHours(), 2) + ':' +
524
520
  padStart(marker.getUTCMinutes(), 2) + ':' +
@@ -565,7 +561,6 @@ function parse(str) {
565
561
 
566
562
  class DateEnv {
567
563
  constructor(settings) {
568
- var _a;
569
564
  this.timeZone = settings.timeZone;
570
565
  this.calendarSystem = createCalendarSystem(settings.calendarSystem);
571
566
  this.locale = settings.locale;
@@ -582,9 +577,8 @@ class DateEnv {
582
577
  this.weekNumberFunc = settings.weekNumberCalculation;
583
578
  }
584
579
  this.weekText = settings.weekText;
585
- this.weekTextShort = (_a = settings.weekTextShort) !== null && _a !== void 0 ? _a : settings.weekText;
580
+ this.weekTextShort = settings.weekTextShort ?? settings.weekText;
586
581
  this.cmdFormatter = settings.cmdFormatter;
587
- this.defaultSeparator = settings.defaultSeparator;
588
582
  }
589
583
  // Creating / Parsing
590
584
  createMarker(input) {
@@ -792,25 +786,23 @@ class DateEnv {
792
786
  }
793
787
  return weekOfYear(marker, this.weekDow, this.weekDoy);
794
788
  }
795
- // TODO: choke on timeZoneName: long
796
- format(marker, formatter) {
797
- return formatter.format({
789
+ formatToParts(marker, formatter) {
790
+ return formatter.formatToParts({
798
791
  marker,
799
792
  timeZoneOffset: this.offsetForMarker(marker),
800
793
  }, this);
801
794
  }
802
- // Unlike format(), returns plain string!
803
- formatRange(start, end, formatter, dateOptions = {}) {
795
+ formatRangeToParts(start, end, formatter, dateOptions = {}) {
804
796
  if (dateOptions.isEndExclusive) {
805
797
  end = addMs(end, -1);
806
798
  }
807
- return formatter.formatRange({
799
+ return formatter.formatRangeToParts({
808
800
  marker: start,
809
801
  timeZoneOffset: this.offsetForMarker(start),
810
802
  }, {
811
803
  marker: end,
812
804
  timeZoneOffset: this.offsetForMarker(end),
813
- }, this, dateOptions.defaultSeparator);
805
+ }, this);
814
806
  }
815
807
  /*
816
808
  DUMB: the omitTime arg is dumb. if we omit the time, we want to omit the timezone offset. and if we do that,
@@ -831,10 +823,9 @@ class DateEnv {
831
823
  if (this.timeZone === 'UTC') {
832
824
  return new Date(ms);
833
825
  }
834
- const zdt = Temporal.Instant.fromEpochMilliseconds(ms)
835
- .toZonedDateTimeISO(this.timeZone);
826
+ const zdtFields = ZonedDateTimeFns.getFields(InstantFns.toZonedDateTimeISO(InstantFns.fromEpochMilliseconds(ms), this.timeZone));
836
827
  return new Date(// a "Date Marker", which is like PlainDateTime
837
- Date.UTC(zdt.year, zdt.month - 1, zdt.day, zdt.hour, zdt.minute, zdt.second, zdt.millisecond));
828
+ Date.UTC(zdtFields.year, zdtFields.month - 1, zdtFields.day, zdtFields.hour, zdtFields.minute, zdtFields.second, zdtFields.millisecond));
838
829
  }
839
830
  offsetForMarker(m) {
840
831
  if (this.timeZone === 'local') {
@@ -843,7 +834,7 @@ class DateEnv {
843
834
  if (this.timeZone === 'UTC') {
844
835
  return 0;
845
836
  }
846
- return new Temporal.PlainDateTime(m.getUTCFullYear(), m.getUTCMonth() + 1, m.getUTCDate(), m.getUTCHours(), m.getUTCMinutes(), m.getUTCSeconds(), m.getUTCMilliseconds()).toZonedDateTime(this.timeZone).offsetNanoseconds / (1000000000 * 60);
837
+ return ZonedDateTimeFns.offsetNanoseconds(PlainDateTimeFns.toZonedDateTime(PlainDateTimeFns.create(m.getUTCFullYear(), m.getUTCMonth() + 1, m.getUTCDate(), m.getUTCHours(), m.getUTCMinutes(), m.getUTCSeconds(), m.getUTCMilliseconds()), this.timeZone)) / (1000000000 * 60);
847
838
  }
848
839
  // Conversion
849
840
  toDate(m) {
@@ -853,58 +844,272 @@ class DateEnv {
853
844
  if (this.timeZone === 'UTC') {
854
845
  return new Date(m.valueOf()); // make sure it's a copy
855
846
  }
856
- return new Date(new Temporal.PlainDateTime(m.getUTCFullYear(), m.getUTCMonth() + 1, m.getUTCDate(), m.getUTCHours(), m.getUTCMinutes(), m.getUTCSeconds(), m.getUTCMilliseconds()).toZonedDateTime(this.timeZone).epochMilliseconds);
847
+ return new Date(ZonedDateTimeFns.epochMilliseconds(PlainDateTimeFns.toZonedDateTime(PlainDateTimeFns.create(m.getUTCFullYear(), m.getUTCMonth() + 1, m.getUTCDate(), m.getUTCHours(), m.getUTCMinutes(), m.getUTCSeconds(), m.getUTCMilliseconds()), this.timeZone)));
857
848
  }
858
849
  }
859
850
 
860
- /*
861
- TODO: fix the terminology of "formatter" vs "formatting func"
862
- */
863
- /*
864
- At the time of instantiation, this object does not know which cmd-formatting system it will use.
865
- It receives this at the time of formatting, as a setting.
866
- */
867
- 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 {
868
1079
  constructor(cmdStr) {
869
1080
  this.cmdStr = cmdStr;
870
1081
  }
871
- format(date, context, betterDefaultSeparator) {
872
- const res = context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(date, null, context, betterDefaultSeparator));
873
- // array of parts?
874
- if (typeof res === 'object') {
875
- 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;
876
1086
  }
877
- // otherwise, just a string
878
- return [res, [{ type: 'literal', value: res }]];
879
- }
880
- // Unlike format(), returns plain string!
881
- formatRange(start, end, context, betterDefaultSeparator) {
882
- const res = context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(start, end, context, betterDefaultSeparator));
883
- // array of parts?
884
- if (typeof res === 'object') {
885
- 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
+ }));
886
1096
  }
887
- // otherwise, just a string
888
- return res;
1097
+ return [{ source: 'shared', type: 'literal', value: res }];
889
1098
  }
890
1099
  }
891
1100
 
892
- class FuncFormatter {
1101
+ class FuncDateFormatter {
893
1102
  constructor(func) {
894
1103
  this.func = func;
895
1104
  }
896
- format(date, context, betterDefaultSeparator) {
897
- const str = this.func(createVerboseFormattingArg(date, null, context, betterDefaultSeparator));
898
- return [
899
- str,
900
- // HACK. In future versions, allow func-formatters to return parts?
901
- [{ type: 'literal', value: str }],
902
- ];
1105
+ formatToParts(date, context) {
1106
+ const str = this.func(createVerboseFormattingArg(date, null, context));
1107
+ return [{ type: 'literal', value: str }];
903
1108
  }
904
- // Unlike format(), returns plain string!
905
- formatRange(start, end, context, betterDefaultSeparator) {
906
- 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 }];
907
1112
  }
908
1113
  }
909
1114
 
910
- 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.7",
3
+ "version": "7.0.0-rc.1",
4
4
  "keywords": [
5
5
  "headless",
6
6
  "calendar",
@@ -9,7 +9,7 @@
9
9
  "title": "Headless Calendar Library",
10
10
  "description": "Headless calendar library by the makers of FullCalendar",
11
11
  "peerDependencies": {
12
- "temporal-polyfill": "^0.3.0"
12
+ "temporal-polyfill": "^0.3.2"
13
13
  },
14
14
  "type": "module",
15
15
  "homepage": "https://fullcalendar.io",