@dereekb/dbx-form 13.10.5 → 13.10.6

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.
@@ -241,6 +241,18 @@ class DbxCalendarScheduleSelectionStore extends ComponentStore {
241
241
  currentSelectionValueStart$ = this.currentSelectionValue$.pipe(map((x) => x?.dateScheduleRange.start), distinctUntilChanged(isSameDate), shareReplay(1));
242
242
  currentSelectionValueDateCellTimingDateFactory$ = this.currentSelectionValue$.pipe(map((x) => (x ? dateCellTimingDateFactory({ startsAt: x.dateScheduleRange.start, timezone: x.dateScheduleRange.timezone }) : undefined)), shareReplay(1));
243
243
  currentSelectionValueDateCellDurationSpanExpansion$ = this.currentSelectionValue$.pipe(map((x) => (x ? expandDateCellScheduleRange({ dateCellScheduleRange: x.dateScheduleRange }) : [])), shareReplay(1));
244
+ /**
245
+ * State-anchored coordinate contract: the emitted indexes are anchored at
246
+ * `state.start` (== `filter.start` when a filter is set, otherwise `today` from
247
+ * `initialCalendarScheduleSelectionState()`). Consumers can use them directly
248
+ * with `state.indexFactory(date)`.
249
+ *
250
+ * This holds because `currentSelectionValue.dateScheduleRange.start` always
251
+ * equals `state.start` for filter-relative outputs, so the expansion's `i`
252
+ * values share the same anchor. If a future change re-introduces a non-
253
+ * `state.start` output anchor, translate output indexes back via
254
+ * `state.indexFactory(dateScheduleRange.start)` here.
255
+ */
244
256
  selectionValueSelectedIndexes$ = this.currentSelectionValueDateCellDurationSpanExpansion$.pipe(map((x) => new Set(x.map((y) => y.i))), distinctUntilHasDifferentValues(), shareReplay(1));
245
257
  selectionValueSelectedDates$ = this.currentSelectionValueDateCellTimingDateFactory$.pipe(switchMap((dateFactory) => {
246
258
  return dateFactory ? this.selectionValueSelectedIndexes$.pipe(map((x) => mapValuesToSet(x, (y) => formatToISO8601DayStringForSystem(dateFactory(y))))) : of(new Set());
@@ -577,11 +589,14 @@ function updateStateWithDateCellScheduleRangeValue(state, inputChange) {
577
589
  return state;
578
590
  }
579
591
  if (change != null) {
580
- // The incoming ex indexes are relative to change.start, but toggledIndexes must be
581
- // relative to state.start. Adjust by the offset between them.
582
- const inputStartIndex = state.indexFactory(change.start);
583
- const adjustedEx = inputStartIndex !== 0 && change.ex ? change.ex.map((i) => i + inputStartIndex) : (change.ex ?? []);
584
- const nextState = { ...state, inputStart: change.start, inputEnd: change.end, toggledIndexes: new Set(adjustedEx) };
592
+ // After the legacy-restored output anchor, change.ex is already state-anchored
593
+ // (change.start equals state.start for filter-relative outputs), so no offset
594
+ // is applied. inputStart is clamped to state.minMaxDateRange.start when set so
595
+ // the round-trip preserves the clamp and pre-clamp days don't re-render via the
596
+ // "toggled outside range" branch.
597
+ const minMaxStart = state.minMaxDateRange?.start;
598
+ const clampedInputStart = minMaxStart && minMaxStart.getTime() > change.start.getTime() ? minMaxStart : change.start;
599
+ const nextState = { ...state, inputStart: clampedInputStart, inputEnd: change.end, toggledIndexes: new Set(change.ex ?? []) };
585
600
  return updateStateWithChangedScheduleDays(finalizeNewCalendarScheduleSelectionState(nextState), expandDateCellScheduleDayCodes(change.w || '89'));
586
601
  }
587
602
  return noSelectionCalendarScheduleSelectionState(state); // clear selection, retain disabled days
@@ -923,26 +938,8 @@ function computeScheduleSelectionValue(state) {
923
938
  const rangeStartIndex = systemIndexFactory(rangeStart);
924
939
  const startIndex = systemIndexFactory(startInSystemTimezone);
925
940
  const filterStartIndexOffset = rangeStartIndex - startIndex;
926
- // When minMaxDateRange constrains the start to after filter.start,
927
- // use rangeStart as the output start instead of filter.start.
928
- // This prevents outputting a start date that violates the minMaxDateRange
929
- // and avoids the round-trip corruption when the value is synced back to the store.
930
- if (filterStartIndexOffset > 0 && state.minMaxDateRange?.start) {
931
- // rangeStart already respects minMaxDateRange. Convert it to the filter's timezone for the output.
932
- if (filter.timezone) {
933
- const filterNormal = dateTimezoneUtcNormal(filter.timezone);
934
- start = filterNormal.startOfDayInTargetTimezone(rangeStart);
935
- }
936
- else {
937
- start = rangeStart;
938
- }
939
- // No filter offset exclusions needed since start is at the selection start.
940
- // indexOffset stays as dateCellRange.i (relative to state.start → rangeStart).
941
- }
942
- else {
943
- filterOffsetExcludedRange = range(0, filterStartIndexOffset);
944
- indexOffset = indexOffset - filterStartIndexOffset;
945
- }
941
+ filterOffsetExcludedRange = range(0, filterStartIndexOffset);
942
+ indexOffset = indexOffset - filterStartIndexOffset;
946
943
  }
947
944
  const excluded = computeSelectionResultRelativeToFilter
948
945
  ? allExcluded.filter((x) => {