aboutsummaryrefslogtreecommitdiff
path: root/src/theme/Admonition/Layout/index.js
blob: 14a987b0472ce90a4270fbbdbd6c65d9677e921c (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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */
import React from 'react';
import clsx from 'clsx';
import { ThemeClassNames } from '@docusaurus/theme-common';
import admonitionStyles from '@docusaurus/theme-classic/lib/theme/Admonition/Layout/styles.module.css';
import headingStyles from '@docusaurus/theme-classic/lib/theme/Heading/styles.module.css';

function AdmonitionContainer({type, className, children}) {
  return (
    <div
      className={clsx(
        ThemeClassNames.common.admonition,
        ThemeClassNames.common.admonitionType(type),
        admonitionStyles.admonition,
        className,
      )}
      >
      {children}
    </div>
  );
}
function AdmonitionHeading({icon, id, title}) {
  let depth = 0;
  let trimmedTitle = "";
  // titleにHTML等が含まれている場合は文字列ではなく配列になる
  if(typeof title === "string") {
    // 文字列冒頭の#の数を数える(
    depth = title.match ? (title.toString().match(/^#+/) || [''])[0].length : 0;
    // #を省いたタイトルを得る
    trimmedTitle = depth > 0 ? title.replace(/^#+/, '').trim() : title;  
  } else if (typeof title[0] === "string") {
    depth = title[0].match ? (title[0].match(/^#+/) || [''])[0].length : 0;
    trimmedTitle = depth > 0 ? [title[0].replace(/^#+/, '').trim(), ...title.slice(1)] : title;
  }
  // スクロール位置調整のcss
  const classNames = clsx("anchor", "title", headingStyles.anchorWithStickyNavbar);
  // depthに応じて見出しタグをレンダー
  return (
    <div className={admonitionStyles.admonitionHeading}>
      <span className={admonitionStyles.admonitionIcon}>{icon}</span>
      {(() => {
        if (depth == 3) {
          return(
            <h3
              id={id}
              className={classNames}
            >
              {trimmedTitle}
            </h3>
          )
        } else if (depth == 4) {
          return(
            <h4
              id={id}
              className={classNames}
            >
              {trimmedTitle}
            </h4>
          )
        } else if (depth == 5) {
          return(
            <h5
              id={id}
              className={classNames}
            >
              {trimmedTitle}
            </h5>
          )
        } else if (depth == 6) {
          return(
            <h6
              id={id}
              className={classNames}
            >
              {trimmedTitle}
            </h6>
          )
        } else {
          return(
            <>
              {trimmedTitle}
            </>
          )
        }
      })()}
    </div>
  );
}
function AdmonitionContent({children}) {
  return children ? (
    <div className={admonitionStyles.admonitionContent}>{children}</div>
  ) : null;
}
export default function AdmonitionLayout(props) {
  const {type, icon, title, children, className, id} = props;
  return (
    <AdmonitionContainer type={type} className={className}>
      <AdmonitionHeading title={title} icon={icon} id={id} />
      <AdmonitionContent>{children}</AdmonitionContent>
    </AdmonitionContainer>
  );
}