summaryrefslogtreecommitdiff
path: root/src/util/pagenation.ts
blob: 15ee01bce4324f21dbf46587196b9034338192a5 (plain)
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
export type PagenationProp = {
  now: number,
  max: number,
  between: number,
}
export function createPagenation(prop: PagenationProp) {
  if (prop.between < 0) {
    throw new Error(`betweenは0以上にして下さい`);
  }
  if (prop.max < 0) {
    throw new Error(`maxは0以上にして下さい`);
  }
  if (prop.now < 0) {
    throw new Error(`nowは0以上にして下さい`);
  }
  if (prop.max < prop.now) {
    throw new Error(`nowの値はmaxと同じか、より小さな値にして下さい. now:${prop.now} , max:${prop.max}`);
  }
  if (prop.max == 0) {
    return [];
  }
  const MIN = 1;
  // 左・中・右の3ブロックの変数を作成
  const blockLeft = MIN;
  let blockMiddle = [
    ...Array.from({ length: prop.between }).map((_, index) => {
      const i = prop.now - prop.between + index;
      return i;
    }),
    prop.now,
    ...Array.from({ length: prop.between }).map((_, index) => {
      const i = prop.now + index + 1;
      return i;
    }),
  ];
  blockMiddle = blockMiddle.filter(i => {
    if (i <= blockLeft) {
      return false;
    }
    if (prop.max <= i) {
      return false;
    }
    return true;
  });
  const blockRight = prop.max;
  type A = { type: "back", key: string, link: number | null };
  type B = { type: "next", key: string, link: number | null };
  type C = { type: "sp", key: string, };
  type D = { type: "num", key: string, link: number | null, num: number }
  // 結合を作成
  const pageIdList: (A | B | C | D)[] = [];
  {
    // 左戻る矢印
    if (prop.now == MIN) {
      pageIdList.push({ type: "back", key: "back", link: null });
    } else {
      pageIdList.push({ type: "back", key: "back", link: prop.now - 1 });
    }
    // 最初のページ
    pageIdList.push({ type: "num", key: `p-${blockLeft}`, link: blockLeft, num: blockLeft });
    let lastPageId = blockLeft;
    // 左と中の間の…を入れるかどうか
    if (0 < blockMiddle.length && lastPageId + 1 != blockMiddle[0]) {
      pageIdList.push({ type: "sp", key: "sp-left" });
    }
    blockMiddle.forEach(m => {
      pageIdList.push({ type: "num", key: `p-${m}`, link: m, num: m });
      lastPageId = m;
    });
    if (0 < blockMiddle.length && lastPageId + 1 != blockRight) {
      // 最後のページ
      pageIdList.push({ type: "sp", key: "sp-right" });
    }
    if (lastPageId != blockRight) {
      pageIdList.push({ type: "num", key: `p-${blockRight}`, link: blockRight, num: blockRight });
      lastPageId = blockRight;
    }
    // 右矢印
    if (prop.now == prop.max) {
      pageIdList.push({ type: "next", key: "next", link: null });
    } else {
      pageIdList.push({ type: "next", key: "next", link: prop.now + 1 });
    }
    pageIdList.forEach(p => {
      if ("link" in p && p.link == prop.now) {
        p.link = null;
      }
    })
  }
  return pageIdList
}