Blame view

天文台pc/tianwentai-ui/node_modules/react-day-picker/src/contexts/Focus/utils/getNextFocus.ts 2.31 KB
bc518174   王天杨   提交两个项目文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
  import {
    addDays,
    addMonths,
    addWeeks,
    addYears,
    endOfISOWeek,
    endOfWeek,
    max,
    min,
    startOfISOWeek,
    startOfWeek
  } from 'date-fns';
  
  import { DayPickerContextValue } from 'contexts/DayPicker';
  import { getActiveModifiers } from 'contexts/Modifiers';
  import { Modifiers } from 'types/Modifiers';
  
  export type MoveFocusBy =
    | 'day'
    | 'week'
    | 'startOfWeek'
    | 'endOfWeek'
    | 'month'
    | 'year';
  
  export type MoveFocusDirection = 'after' | 'before';
  
  export type FocusDayPickerContext = Partial<
    Pick<
      DayPickerContextValue,
      'ISOWeek' | 'weekStartsOn' | 'fromDate' | 'toDate' | 'locale'
    >
  >;
  
  export type FocusDayOptions = {
    moveBy: MoveFocusBy;
    direction: MoveFocusDirection;
    context: FocusDayPickerContext;
    modifiers?: Modifiers;
    retry?: { count: number; lastFocused: Date };
  };
  
  const MAX_RETRY = 365;
  
  /** Return the next date to be focused. */
  export function getNextFocus(focusedDay: Date, options: FocusDayOptions): Date {
    const {
      moveBy,
      direction,
      context,
      modifiers,
      retry = { count: 0, lastFocused: focusedDay }
    } = options;
    const { weekStartsOn, fromDate, toDate, locale } = context;
  
    const moveFns = {
      day: addDays,
      week: addWeeks,
      month: addMonths,
      year: addYears,
      startOfWeek: (date: Date) =>
        context.ISOWeek
          ? startOfISOWeek(date)
          : startOfWeek(date, { locale, weekStartsOn }),
      endOfWeek: (date: Date) =>
        context.ISOWeek
          ? endOfISOWeek(date)
          : endOfWeek(date, { locale, weekStartsOn })
    };
  
    let newFocusedDay = moveFns[moveBy](
      focusedDay,
      direction === 'after' ? 1 : -1
    );
  
    if (direction === 'before' && fromDate) {
      newFocusedDay = max([fromDate, newFocusedDay]);
    } else if (direction === 'after' && toDate) {
      newFocusedDay = min([toDate, newFocusedDay]);
    }
    let isFocusable = true;
  
    if (modifiers) {
      const activeModifiers = getActiveModifiers(newFocusedDay, modifiers);
      isFocusable = !activeModifiers.disabled && !activeModifiers.hidden;
    }
    if (isFocusable) {
      return newFocusedDay;
    } else {
      if (retry.count > MAX_RETRY) {
        return retry.lastFocused;
      }
      return getNextFocus(newFocusedDay, {
        moveBy,
        direction,
        context,
        modifiers,
        retry: {
          ...retry,
          count: retry.count + 1
        }
      });
    }
  }