🐷

Streamlitカスタムコンポーネント開発で直面したiframeの制限について

に公開

はじめに

こんにちは。データエンジニアの山口歩夢です!

最近、Streamlitで日本語対応の日付選択コンポーネントを開発しました。標準のst.date_inputは英語表記のみとなっております。以下のissuesが挙がっていることもあり、曜日や月を日本語で表示するUIを日本のユーザー向けに提供したいと思い実装してみました。

https://github.com/streamlit/streamlit/issues/7865

開発の過程でStreamlit のカスタムコンポーネントが持つ制約にぶつかり、思うようにUIを実装できなかったので、そのお話をします。これらの制約があることから、基本的にはStreamlitが公式で提供しているst.date_inputの使用を推奨します。

作成したコンポーネントは以下のようなものになっております。

streamlit_japanese_date_inputコンポーネント

https://github.com/gussan-me/streamlit_japanese_date_input

直面した課題

カスタムコンポーネントの制約によって、UI実装に課題があったと前述しましたが、具体的には以下の課題がありました。

1. 自作コンポーネントのカレンダーはStreamlitの公式ウィジェットに被せて表示できない

まず、一つ目の課題として、自作コンポーネントで作成した日付入力ウィジェットのカレンダーを、Streamlitの公式ウィジェットに被せて表示することができないという点がありました。

以下で動作について見ていきます。
まずst.date_inputjapanese_date_inputの下部に、st.dividerを設置します。st.dividerは以下の赤線の位置にあります。

そして次に、st.date_inputをクリックして、カレンダーを出力してみます。st.dividerの上にかぶさるようにカレンダーが出力されていることが分かります。このおかげで、UIが崩れることなくカレンダーの出力をすることができます。

次に、自作のコンポーネントのカレンダーを出力してみます。するとst.dividerを下に押し下げてスペースを確保したうえでカレンダーが表示され、UIが崩れてしまいます。
これがまず一つ目の課題でした。

2. アプリの幅を狭めるとカレンダーが見切れる

2つ目の課題として、自作コンポーネントのカレンダーは幅が狭いとカレンダーが見切れてしまうという点がありました。

st.date_inputであれば、このようにスペース狭い所でカレンダーを開いた場合も、他のウィジェットに被さるように表示されるため、きれいに表示されます。

次にstreamlit_japanese_date_inputの方を見てみます。更に幅を狭めるとカレンダーの幅が狭まり、やや見づらくなってしまいます。

最初はカレンダーの大部分が途切れてしまうようになっていたのですが、CSSを修正しアプリの表示幅によって動的にカレンダーの大きさが変わるように実装をし、ある程度見やすくなるように実装しました。
しかし、更に幅を狭めていくと以下のようにカレンダーが見切れてしまうため、十分な幅をとって使用するようREADMEに記載してあります。

以上が2つ目の課題でした。

原因

色々な課題が発生しましたが、このような課題にぶつかった理由は、前述した通りStreamlitにある制約があるためでした。
Streamlitのカスタムコンポーネントは、以下の図ようにStreamlitアプリ内でiframeの枠内に埋め込まれるかたちでのみ使用できるようになっています。
今回の場合で言うと、カレンダーを出力する際、日付入力ウィジェットをクリックした後、iframeの幅を広げたうえで、その中にカレンダーを表示する必要があったということです。そのため、どうしても周囲のUIの位置をずらし、iframeのスペースを確保する必要があります。

st.date_inputのように他のStreamlitのコンポーネントに被せて表示したい場合、Streamlit本体に修正を加えるかたちで実装するしかありません。

解決策

こちらのコンポーネントを実装するにあたり、カレンダーやUIが崩れないよう、可能な限りCSSを調整することで見やすいよう実装しました。

しかし、現状ではUIの安定性や美しさを考えると、公式が提供するst.date_inputを使用するのが最適だと考えています。
特にクリックでコンポーネントが出現するようなUIは、iframeの制約により崩れやすいため、可能な限り公式コンポーネントを活用することをおすすめします。

まとめ

今回のStreamlitカスタムコンポーネントの開発では、iframeによる制限があり、それを理解したうえで、制限の範囲内でカスタムコンポーネント作りをすることが大切だということを学びました。

その他、Streamlitの入門的な内容については、私が執筆した以下の書籍でも詳しく解説しています。ぜひご覧ください!

https://nextpublishing.jp/book/18323.html

Snowflake Data Heroes

Discussion