Skip to content
Go back

Astroテーマを自分用に修正するときのメモ・12

Astroテーマを改造するときのメモをまとめました。

AstroコンポーネントをMarkdownから使う

  • Astro.jsのコンポーネントはMDXから呼び出せるようなので、Astro Iconを使ってMarkdownでアイコンを表示させることもできる
  • MDXを使うには:
    • npmで@astrojs/mdxパッケージを追加する
    • astro.config.tsのintegrationsmdx()を追加する
    • Markdownファイルの拡張子をmdxにする
    • 合わせて、コンテンツコレクションが.mdxを対象に含めるようにパターンを書き換える
  • <Content />components属性で列挙されたモジュールがMDXで使えるようになる
    • Astro Iconの場合、import { Icon } from "astro-icon/components";でインポートして<Content components={{Icon}} />と書くと、MDXで<Icon />が使えるようになる

ツールチップ表示

  • マウスホバーで表示される要素を作りたい
  • Astroでは:
    • import "@/styles/tooltip.css";でCSSを読み込む
    • スクリプトでDOMを操作するので、<script src="../scripts/tooltip.ts"></script></body>の手前に置く
      • src内にあるtsファイルはちゃんとトランスパイルしてくれている?
  • CSSは以下のようにしてみた
/* ツールチップのターゲット */
.tooltip {
  position: relative;
  text-decoration: dotted underline;
}

/* ツールチップのコンテンツ */
.tooltip-content {
  /* 真上に表示 */
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);

  /* 手前に表示 */
  z-index: 10;

  /* 外枠 */
  border: 1px solid var(--color-border);
  border-radius: 4px;
  padding: 4px 8px;
  margin-bottom: 7px;

  /* 中身 */
  background-color: var(--color-background);
  width: max-content;
  max-width: 80ch;
  box-sizing: border-box;
  overflow-wrap: break-word;
  text-align: center;
  font-size: 0.8rem;

  /* デフォルトで非表示 */
  opacity: 0;
  visibility: hidden;

  /* スッと現れる */
  transition: opacity 0.1s ease-in-out;
}

/* ツールチップのターゲットとコンテンツの隙間にカーソル判定を加える */
.tooltip-content::before {
  content: "";

  position: absolute;
  top: 100%;
  left: 0%;
  width: 100%;
  height: 8px;

  pointer-events: auto;
}

/* ツールチップの吹き出し */
.tooltip-content::after {
  content: "";

  /* 真上に表示 */
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);

  /* ▼を描く */
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 6px solid var(--color-border);
}

/* ツールチップに触れたとき */
.tooltip:hover .tooltip-content {
  /* 表示 */
  opacity: 1;
  visibility: visible;
}
  • ツールチップが画面外にはみ出すことがあるので、位置調整してみる
    • もっと良いやり方がありそう
// ツールチップが画面外に出ないように位置を調整するイベントリスナーを追加する
for (const tooltip of document.querySelectorAll<HTMLElement>(".tooltip")) {
  function listener(this: HTMLElement) {
    const content = this.querySelector<HTMLElement>(".tooltip-content");
    if (content === null) return;

    // 初期位置でのツールチップの矩形を調べる
    content.style.maxWidth = "80ch";
    content.style.left = "50%";
    content.style.right = "auto";
    content.style.transform = "translateX(-50%)";
    let rect = content.getBoundingClientRect();

    // ツールチップが画面に収まらないなら、小さくする
    if (rect.width > document.documentElement.clientWidth) {
      content.style.maxWidth = `${document.documentElement.clientWidth}px`;
      rect = content.getBoundingClientRect();
    }

    // ツールチップが画面からはみ出さないようにずらす
    if (rect.left < 0) {
      content.style.left = `${-tooltip.offsetLeft}px`;
      content.style.transform = "none";
    } else if (rect.right > document.documentElement.clientWidth) {
      content.style.left = `${document.documentElement.clientWidth - tooltip.offsetLeft - rect.width}px`;
      content.style.transform = "none";
    }
  }
  tooltip.addEventListener("mouseenter", listener);
  tooltip.addEventListener("touchstart", listener);
}