Skip to content

Latest commit

 

History

History
278 lines (184 loc) · 20.6 KB

File metadata and controls

278 lines (184 loc) · 20.6 KB

@components/README

ここでは,@components(このフォルダ,src/componentsのことです)にあるコンポーネントについて説明します.コンポーネントを作成する際は,まずこの説明を読んでから作成してください.

コンポーネントはHTMLの要素を返す関数で,複数ページに記述されている内容を共通化したり,そのようなコンポーネントを作るために使われたりします.またコンポーネントには,言語(日本語と英語)に依存しないもの,言語をpropで受け取って出し分けるもの,言語ごとに別々に定義されているものの3種類があります.

このファイルの説明は,Markdownに関する基礎知識に加え,以下の2つのドキュメントを読んでいることを前提としています:

  • What is MDX?:MDXに関する基本的な説明
  • スロット:Astroのコンポーネントに子要素を埋め込む「スロット」に関する説明

コンポーネントを作るために使うコンポーネント等

以下の2つの型(コンポーネントがどのようなpropを受け取るかという情報)は複数のコンポーネントの引数として利用されるため,このファイルで定義したものをそれぞれのコンポーネントで参照しています.

  • Lang:uteleconポータルサイトが対応する言語です.日本語 ("ja") と英語 ("en") です.
  • Variantsystems/以下のコンポーネントが使われるページの種類です.

条件分岐コンポーネント

条件によって表示される内容を変えるコンポーネントです.三項演算子などを回避するために利用します特に.mdxでは三項演算子等を利用すると非常に読みづらくなるため,積極的に利用してください.これらのコンポーネントは言語に依存しません(prop langを取りません).utilsにあります.

利用例:ja/systems/utokyo_account/ChangePassword.mdx

prop condがtrueの場合だけ中身の要素が表示されます.また,slot="else"とした要素がある場合,それらは prop condがfalseの場合だけ表示されます.

<If cond={props.variant === "oc"}>
  真の場合の内容
</If>
<If cond={props.variant === "oc"}>
  <Fragment>真の場合の内容</Fragment>
  <Fragment slot="else">偽の場合の内容</Fragment>
</If>

注:.mdxの場合,JSXの中身もMarkdownとして解釈されます.また,Markdownでは単にテキストを書いた場合は<p>要素として解釈されます.よって,1つ目の例でprops.variant === "oc"のときは以下のHTMLが出力されます:

<p>真の場合の内容</p>

一方,FragmentはJSXで用いられる「空のタグ」で,JSXとして認識されますが,HTMLとしては何も出力されません.よって,2つ目の例でprops.variant === "oc"のときは以下のHTMLが出力されます:

真の場合の内容

利用例:ja/systems/utokyo_account/ChangePassword.mdx

prop variantの値によって,表示する要素が切り替わります.JavaScriptのswitchと違い,予め決められた値でしか使えません.値に対応するslot="<variant>"の要素を指定しない場合,何も表示されません.

<Switch variant={props.variant}>
  <Fragment slot="oc">学生向けの内容</Fragment>
  <Fragment slot="faculty_members">教職員向けの内容</Fragment>

  - 学生向けの内容
  - 教職員向けの内容
  {:slot="individual"}
</Switch>

注:BlockIALPluginにより,.mdおよび.mdxでは任意の属性を上のようなsyntaxで指定できます.これは.astroで用いられるslot属性も含まれます.よって,上の例でprops.variant === "individual"のときは以下のHTMLが出力されます:

<ul>
  <li>学生向けの内容</li>
  <li>教職員向けの内容</li>
</ul>

@components/{ja,en}/systemsで利用するコンポーネント

@components/{ja,en}/systemsのコンポーネントを作るために利用するコンポーネントです.コンポーネントの作成を簡潔にするだけでなく,ポータルサイトを読む利用者が不要な違和感なく読めるように見え方を統一する役割もあります.積極的に利用してください.これらのコンポーネントは言語間で共通化されています(prop langを取ります).utilsにあります.

利用例:ja/systems/utokyo_account/index.mdx

/oc/#important/oc/#othersで共通するコンポーネントを作るために利用します.langを指定してください.

  • variant === "oc"かつshortがtrueの場合,slot="important"の要素だけが表示されます.
  • variant === "oc"かつshortがfalseの場合,slot="important"の要素は「再掲」と表示されて折りたたまれ,他の要素は表示されます.
  • variant === "oc"でない場合,slot="important"の要素と他の要素が表示されます.

slot="important"以外の要素は<li>に包む必要がありますslot="important"の要素は<li>に包まないでください

利用例:ja/systems/eccs_cloud_email/Access.mdx

手順の末尾にトラブルシュート情報を折りたたみで表示するために利用します.langを指定してください.supportがtrueの場合,中身の後にサポート窓口に案内する文章が表示されます.

利用例:ja/systems/zoom/SigninBrowserHelpExisting.mdx

トラブルシュート情報の1項目を表示するコンポーネントを作るために利用します.手順の末尾にまとめて項目を表示する場合と,手順の途中に折りたたみで表示する場合を出し分ける機能があります.langを指定してください. slot="problem"に想定される問題を,slot="solution"にその解決方法を書いてください.いずれもインライン要素として渡すため,Fragmentを利用してください. その他の中身は,折りたたみの場合(type="details")および通常の場合(type="default")だけ表示されます.

利用例:ja/systems/utokyo_account/ChangePassword.mdx

サポート窓口に案内する文章を表示するために利用します.langを指定してください.showがtrueの場合のみ表示されます.

特殊なコンポーネント

利用例:pages/Notice.astro

@data以下,またはフロントマターにMarkdownで定義されているデータを表示するために利用します.prop contentにMarkdownを渡すと,それがHTMLに変換されて表示されます.コンポーネントからコンポーネントにマークアップを渡すために利用しないでください.代わりに,

  • .mdxのコンポーネントに渡す場合:propsJSX.Elementを渡して,{props.hoge}として埋め込んでください.
  • .astroのコンポーネントに渡す場合:slotを利用してください.

その他のコンポーネント

利用例:ja/mfa/common/AltAddMethod.mdx

指定した画像の上に,矢印を重ねて描画するコンポーネントです.操作方法を説明するスクリーンショットなどで,画像自体を編集せずに,注目したい箇所を指す矢印を加えることができます.

以下に,各 props の説明を示します.

  • image (必須,ImageMetadata 型) … 元となる画像を指定します.Astro の Image コンポーネントを使用する際と同様に,import SomeImage from './some_image.png'; のようにインポートした画像を image={SomeImage} のように props として渡します.
  • x, y (必須) … 描画する矢印の先の位置を座標で指定します.画像の左上端を原点 (0, 0) とし,右向きに x 軸,下向きに y 軸の正方向がある座標系を用います.
    • ピクセル (px) 単位で指定する場合 … x="320" y="480" のように string 型,あるいは x={320} y={480} のように number 型の数値で,元の画像のピクセル数に従って指定します.
    • 画像の縦横に対する割合 (%) で指定する場合 … x="25%" y="30%" のように,末尾に % をつけた string 型で指定します.
  • scale (number 型) … 矢印の大きさを,後述するデフォルトの矢印に対する拡大倍率で指定します.省略した場合は 1 となります.デフォルトの矢印は,長さが画像の長辺に対して 15%,幅が画像の長辺に対して約 1.6% です.
  • angle (number 型) … 矢印の角度を度数法 (°, deg) で指定します.省略した場合は 0 となります.デフォルトの矢印は右を指す向き (→) で描画され,angle を指定した場合は矢印の先を中心として時計回りに回転移動します.
    • 例 … angle={90}:下向き(↓),angle={-135}:左上向き(↖)
  • color (string 型) … 矢印の塗り潰し色を指定します.省略した場合は #ff3333 が用いられます.
  • class (string 型) … 描画される画像に適用するCSSクラスを指定します.複数指定する場合は半角スペースを空けて並べます.
  • outerClass (string 型) … 描画される画像を包む <div> タグに適用するCSSクラスを指定します.複数指定する場合は半角スペースを空けて並べます.
    • 注:ArrowOverlay は内部的には <div> タグの中に Image コンポーネントと <svg> タグを並べた形になっており,指定したCSSクラスはこの <div> タグに適用されます.

タブUIのコンポーネントです.タブを選択することにより,ユーザーが表示内容を切り替えることができます.

また,複数のタブUIの選択内容を同期させることができ,URLのsearch paramsを通して事前に選択内容を指定することもできます(サポート窓口で活用できると思われます).

利用するには,まず利用したいタブグループ(選択内容が同期されるタブUIの集合)ごとにAstroコンポーネントを以下のように作成してください.

---
import Tabs from "@components/utils/tabs/Tabs";
---

<Tabs client:visible queryKey="os" defaultTab="pleaseSelect">
  <Fragment slot="panel.pleaseSelect">
    上のタブからOSを選択してください.
  </Fragment>
  <Fragment slot="tab.windows">
    Windows
  </Fragment>
  <Fragment slot="panel.windows">
    <slot name="windows" />
  </Fragment>
  <Fragment slot="tab.mac">
    Mac
  </Fragment>
  <Fragment slot="panel.mac">
    <slot name="mac" />
  </Fragment>
</Tabs>

主要なパラメータを以下に示します:

  • client:visible:おまじないです.
  • queryKey … どのクエリパラメータを使用するか指定します.必須です.
    • 例:queryKey="os" とすると,タブの選択内容がURLの ?os=windows のようなクエリパラメータと同期します.
  • defaultTab … 初期状態でどのタブを選択しているかを指定します.必須です.
  • slotの名前 (<slot name="...">) … ドットで区切られた文字列で,タブ名などを指定します.
    • 書式 … tab/panel + . + タブ名
      • tab/panel … 当該slotがタブ本体か,タブを選択すると表示されるパネルかを指定します.
      • タブ名 … タブとパネルの組ごとに異なるタブ名を指定してください.
        • camelCase で記述してください.kebab-case などにすると正しく動作しません1
    • 例:tab.windowsを指定したタブを押すと,panel.windows を指定したパネルが表示されます.
  • タブが表示される順番は書いた順番に従います.

原則としてタブとパネルはセットですが,上の例の pleaseSelect のように,タブを作らずにパネルだけにしておいて defaultTab に指定すると,何も選択されていないときのメッセージを表示できます.

利用したいページでは,以下のように上で作成したAstroコンポーネントを通して使います.

import OSTabs from "@components/ja/hogehoge/OSTabs.astro";

<OSTabs>
  <Fragment slot="windows">
    Windowsの説明がここに入ります
  </Fragment>
  <Fragment slot="mac">
    Macの説明がここに入ります
  </Fragment>
</OSTabs>

複数ページで記述されている内容を共通化するコンポーネント

各システムの基本的な手順を説明するコンポーネント

@components/{ja,en}/systemsの直下には,システム名を冠するフォルダだけが置いてあり,それぞれのフォルダには以下のようなコンポーネントが定義されています.これらのコンポーネントは言語ごとに別々に定義されています(prop langを取りません).フォルダ名・ファイル名やコンポーネントの構造は言語間で共通です.

「基本単位」

@components/{ja,en}/systemsにあるコンポーネント群のうち,1つの<ol>を含むコンポーネントが「基本単位」のコンポーネントです.@components/{ja,en}/systemsは,システム等の基本的な手順の説明を,この基本単位で分割して整理・共通化することを目的としています.よって,原則として基本単位1つを1ファイルで記述します.例えばja/systems/utokyo_account/ChangePassword.mdxは,1つの<ol>で「UTokyo Accountのパスワードを変更する」という作業の手順を説明しており,手順を複数のページで掲載するために利用されています.

index.mdx

各システムのindex.mdxは,基本単位のコンポーネントを1つの<ul>に束ね,/oc/で表示することを目的としています.さらに,/oc/#importantで説明されるシステムのindex.mdxは,後述のImportantを利用して,/oc/#important/oc/#othersで説明を共通化する責務をも帯びています.

その他

その他,後述のHelpItemを利用した共通化が必要な場合など,基本単位よりも細かいコンポーネントを作成し,基本単位のコンポーネントで利用することがあります.

Courses.md

@components/{ja,en}/Courses.md,授業の形態について説明するコンポーネントです./faculty_members/および/online/courses/で利用されています.言語ごとに別々に定義されています(prop langを取りません).

Emergency.mdx

@components/Emergency.mdxは,緊急時に広い範囲に影響が及ぶ不具合が発生した場合などに主要なページに掲示する内容を記述するコンポーネントです./および/supports/に掲示されます.現在は日本語しか存在しません(英語ページでも日本語の同じ内容が掲示されます).

InformationSecurity.mdx

@components/{ja,en}/InformationSecurity.mdxは,情報セキュリティ教育に関する情報を記述するコンポーネントです.複数のシステムが情報セキュリティ教育の受講を必須としているため,それらのページに記述されている説明を共通化するために利用されています.言語ごとに別々に定義されています(prop langを取りません).

InPreparation.mdx

@components/{ja,en}/InPreparation.mdxは,準備中のページを示すコンポーネントです.複数のページを一度に作成する際に,パンくずリストの生成に失敗したり,内部リンクが404 Not Foundになったりすることを防ぐため,仮のページを作る場合に使われます.言語ごとに別々に定義されています(prop langを取りません).

ExcuseForAccuracy.mdx

@components/{ja,en}/ExcuseForAccuracy.mdxは,ページ内の記述が古くなっており正確性に自信が持てず,かつただちにその正確性を検証することも難しいような場合に利用するコンポーネントです.ECCSウェブサイトの閉鎖に伴うuteleconへのコンテンツ移行に際して作成されました.言語ごとに別々に定義されています(prop langを取りません).

外部メディア等を埋め込むコンポーネント

外部メディア等を埋め込み,スタイルを整えるためのコンポーネントです.これらのコンポーネントは言語に依存しません(prop langを取りません)が,埋め込むメディア等によって異なるpropを取ります.embed以下にあります.

@components/embed/YouTube.astroは,YouTube動画を埋め込むためのコンポーネントです.prop src にYouTubeの埋め込み用URL(https://www.youtube.com/embed/から始まるURL)を渡すと,その動画が埋め込まれます.それ以外のprop(titleなど)を指定することもできます.

<YouTube src="動画の埋め込み用URL" />

@components/embed/MaterialIcon.astroは,Googleによって提供されているMaterial Symbols and Iconsを埋め込むためのコンポーネントです.iconプロパティにアイコン名をsnake_caseの文字列として渡すと,対応するアイコンがインラインSVGとして埋め込まれます.また,styleプロパティによりスタイルを指定することもできます(デフォルトはoutlined).SVGタグに追加で属性を適用したい場合はsvgPropsにオブジェクトを渡してください.

@components/embed/FontAwesomeIcon.astroは,Font Awesomeによるアイコンを埋め込むためのコンポーネントです.iconプロパティにアイコン名をkebab-caseの文字列として渡すか,あるいは@fortawesome/free-solid-svg-iconsから直接アイコンをインポートして渡すと,対応するアイコンがインラインSVGとして埋め込まれます.SVGタグに追加で属性を適用したい場合はsvgPropsにオブジェクトを渡してください.

Footnotes

  1. Tabs は React コンポーネントとして実装されています.Astro が React に名前付き slot を渡す際に kebab-casecamelCase に変換しますが,HTML 生成時とクライアント側の hydrate 時で挙動が異なるようです.そのため、変換が行われないようにするために camelCase のみをタブ名として使います.