streamlit-sortable-multiselect の使い方
順序入れ替え可能な Streamlit の multiselect の使い方を紹介します。
はじめに
Streamlit でアプリを作っていると、「複数の項目を選んで、さらにその順番も指定させたい」という場面に出くわすことがあります。標準の st.multiselect は選択こそできますが、順番の制御はできません。
streamlit-sortable-multiselect は、この課題を解決するカスタムコンポーネントです。ドロップダウンで複数の値を選択し、選んだ項目を 上下ボタンで並べ替えられる UI を提供します。アイコン表示・色のカスタマイズ・最大選択数の制限など、実用的な機能も揃っています。
たとえば次のようなケースでは、「何を選んだか」だけでなく「どの順番で選んだか」も重要になります。
- 優先度順のタスク選択
- おすすめ順の技術スタック選択
- 表示順をユーザーに決めてもらう設定画面
- アンケートでのランキング入力
こうした UI を素の Streamlit だけで作ろうとすると、st.multiselect と st.button を組み合わせて状態管理を書く必要があり、コードがやや複雑になります。このコンポーネントを使えば、その部分を 再利用しやすい部品としてまとめて扱える のが大きな利点です。
インストール
pip install streamlit-sortable-multiselect
Python 3.9 以上・Streamlit 1.30 以上が必要です。
通常の Streamlit アプリと同じように、インストール後は import してそのまま使えます。特別な初期化コードは不要で、sortable_multiselect(...) を呼び出すだけでコンポーネントが表示されます。
最初に試すときは、以下のような最小構成の app.py を作って streamlit run app.py で起動すると挙動を確認しやすいです。
基本的な使い方
最もシンプルな使い方は、文字列のリストを options に渡すだけです。
import streamlit as st
from streamlit_sortable_multiselect import sortable_multiselect
selected = sortable_multiselect(
"好きなプログラミング言語を選んでください",
options=["Python", "TypeScript", "Rust", "Go", "Java"],
default=["Python", "TypeScript"],
)
st.write("選択された順番:", selected)
この例では、最初に Python と TypeScript が選択済みの状態で表示されます。ユーザーが UI 上で順序を入れ替えると、selected の中身もその順番に合わせて更新されます。
-
label— コンポーネントの上部に表示されるラベルテキスト -
options— 選択肢の文字列リスト -
default— 初期選択値(リストの順番が初期の並び順になります)
戻り値は list[str] で、ユーザーが並べ替えた順番で返ってきます。
つまり、単に「選ばれたかどうか」だけではなく、並び順まで含めてアプリ側で受け取れる のがポイントです。たとえば上位 3 件だけを採用したり、1 位の項目を別表示したりといった処理が簡単になります。
st.multiselect との違い
標準の st.multiselect でも複数選択はできますが、「選択後の順番変更」は考慮されていません。一方 sortable_multiselect は、選択済みアイテムの順序そのものが意味を持つ 前提で設計されています。
そのため、以下のような要件に向いています。
- 「上から優先度順に並べてください」と指示したい
- 選択済みの並び順をそのまま保存したい
- 順位に応じて色や番号を付けたい
アイコン付きオプション
文字列の代わりに辞書 (label / value / icon_url) を渡すと、各選択肢にアイコンを表示できます。
selected = sortable_multiselect(
"使用言語",
options=[
{"label": "Python", "value": "python", "icon_url": "https://www.python.org/static/favicon.ico"},
{"label": "TypeScript", "value": "typescript", "icon_url": "https://www.typescriptlang.org/favicon-32x32.png"},
{"label": "Rust", "value": "rust", "icon_url": "https://rust-lang.org/static/images/favicon.svg"},
{"label": "Go", "value": "go", "icon_url": "https://go.dev/images/favicon-gopher.png"},
{"label": "Java", "value": "java", "icon_url": "https://www.oracle.com/favicon.ico"},
],
default=["python", "typescript"],
placeholder="言語を追加...",
)
st.write("選択:", selected)
| キー | 必須 | 説明 |
|---|---|---|
label |
✅ | ドロップダウンに表示する文字列 |
value |
✅ | 戻り値として返される文字列 |
icon_url |
— | アイコン画像の URL(省略可) |
注意:
defaultに指定する値はvalueキーの文字列です。
この辞書形式を使うと、表示用の名前 と 内部で扱う値 を分けられます。たとえば UI には TypeScript と表示しつつ、戻り値では typescript を扱う、といった設計ができます。
これは実務でも便利で、表示文言の変更と内部値の安定性を切り分けられます。将来的にラベルを日本語化したい場合でも、value を変えずに済むため、保存済みデータとの整合性を保ちやすくなります。
また、icon_url は必須ではないので、アイコンがある項目だけ画像付きにすることもできます。プロダクト一覧、サービス一覧、言語一覧のように、視認性を上げたい場面で効果的です。
全パラメータ解説
sortable_multiselect(
label,
options,
default=None,
placeholder="Select...",
disabled=False,
show_move_buttons=True,
show_numbers=False,
base_color=None,
order_colors=None,
max_selections=None,
max_selections_placeholder="Selection limit reached",
empty_message="No items selected",
key=None,
)
| パラメータ | 型 | デフォルト | 説明 |
|---|---|---|---|
label |
str |
— | コンポーネント上部のラベル |
options |
list[str | dict] |
— | 選択肢(文字列または辞書のリスト) |
default |
list[str] | None |
None |
初期選択値のリスト(順番が初期並び順) |
placeholder |
str |
"Select..." |
追加用ドロップダウンのプレースホルダー |
disabled |
bool |
False |
True にすると選択・並べ替えが無効化される |
show_move_buttons |
bool |
True |
上下移動ボタンの表示/非表示 |
show_numbers |
bool |
False |
各項目の先頭に 1 始まりの番号を表示 |
base_color |
str | None |
None |
選択済み項目の背景色(CSS カラー文字列) |
order_colors |
dict[int, str] | None |
None |
順位ごとの背景色(例: {1: "#fee2e2", 2: "#dcfce7"}) |
max_selections |
int | None |
None |
最大選択数(None は無制限) |
max_selections_placeholder |
str |
"Selection limit reached" |
上限到達時のプレースホルダー |
empty_message |
str |
"No items selected" |
何も選択されていない場合の表示テキスト |
key |
str | None |
None |
Streamlit コンポーネントキー |
用途ごとに見ると、パラメータは次のように整理できます。
1. 基本設定
labeloptionsdefaultkey
まずはこの 4 つを理解すれば、最低限の利用はできます。特に options と default の値の整合性は重要で、default に存在しない値を入れることはできません。
2. 見た目の調整
placeholdershow_move_buttonsshow_numbersbase_colororder_colorsempty_message
見た目の調整系パラメータを使うと、単なる入力部品ではなく、ランキング UI として意味が伝わる見せ方 ができます。特に show_numbers と order_colors の組み合わせは、優先順位を表現する用途で相性が良いです。
3. 入力制御
disabledmax_selectionsmax_selections_placeholder
フォームの入力段階を制御したい場合に使います。たとえば「最大 3 つまで選んでください」という要件がある場合、max_selections を設定するだけで UI 側の制約まで自然に適用できます。
利用時の注意点
このコンポーネントは使いやすい一方で、いくつか意識しておくとハマりにくいポイントがあります。
-
optionsの値は重複させない
valueが重複するとどの項目が選ばれたのか判別できなくなるため、ユニークな値を使う必要があります。 -
defaultはoptionsに含まれる値だけを使う
特に辞書形式の場合はlabelではなくvalueを指定する点に注意します。 -
同じページで複数使う場合は
keyを付ける
Streamlit コンポーネント全般と同様、複数配置する場合は一意なkeyを付けると状態管理が安定します。
実践サンプル:優先技術スタックランキングアプリ
順番が意味を持つ典型的なユースケースとして、「優先度順でフレームワークを選ぶ」アプリを作ってみます。
import streamlit as st
from streamlit_sortable_multiselect import sortable_multiselect
st.title("優先技術スタック ランキング")
st.caption("上から順に優先度が高い順番に並べ替えてください(最大 5 つ)")
FRAMEWORKS = [
{"label": "Streamlit", "value": "streamlit", "icon_url": "https://streamlit.io/images/brand/streamlit-mark-color.png"},
{"label": "FastAPI", "value": "fastapi", "icon_url": "https://fastapi.tiangolo.com/img/favicon.png"},
{"label": "Django", "value": "django"},
{"label": "Flask", "value": "flask"},
{"label": "LangChain", "value": "langchain"},
{"label": "LlamaIndex", "value": "llamaindex"},
{"label": "Gradio", "value": "gradio"},
{"label": "Dash", "value": "dash"},
]
selected = sortable_multiselect(
"使用するフレームワーク",
options=FRAMEWORKS,
default=["streamlit", "fastapi"],
placeholder="フレームワークを追加...",
show_numbers=True,
show_move_buttons=True,
base_color="#eef2ff",
order_colors={1: "#fee2e2", 2: "#fef9c3", 3: "#dcfce7"},
max_selections=5,
max_selections_placeholder="選択上限(5つ)に達しました",
empty_message="フレームワークが選択されていません",
key="tech_stack",
)
if selected:
st.subheader("あなたの優先ランキング")
for rank, fw in enumerate(selected, start=1):
st.write(f"**{rank}位**: {fw}")
else:
st.info("フレームワークを選択してください。")
このサンプルのポイントは、選択結果をそのままランキングとして表示している ことです。enumerate(selected, start=1) を使うことで、並び替え結果をそのまま 1 位、2 位、3 位として扱えます。
つまり、コンポーネントが返す値は単なる「選択された一覧」ではなく、ユーザーが意味付けした順番付きデータ です。これにより、優先度に応じた推薦ロジックや分岐処理も実装しやすくなります。
ポイント解説
-
show_numbers=True— 各項目の左に「1. 2. 3.」と順位番号が表示されます -
order_colors={1: "#fee2e2", ...}— 1 位は赤系、2 位は黄系、3 位は緑系と色でランクを視覚化 -
max_selections=5— 5 つ選んだ時点でドロップダウンが無効化され、プレースホルダーが切り替わります -
key="tech_stack"— 同一ページに複数のコンポーネントを置く場合は一意のキーが必要です
このように、UI の段階でルールや意味を明確にしておくと、ユーザーは迷わず操作できます。特に「順位がある入力」は自由度が高すぎると使いづらくなるため、番号表示・色分け・選択上限の 3 つは実用上かなり有効です。
こんな用途に向いている
- 採用したい技術の優先順位入力
- 旅行先や本のおすすめランキング
- 業務フローの並び替え
- ダッシュボード上の表示順カスタマイズ
- プロンプトテンプレートや処理順の設定 UI
まとめ
streamlit-sortable-multiselect を使うと、標準の st.multiselect では実現できない 「選択 + 並べ替え」 の UI を数行で追加できます。
| 機能 | 標準 st.multiselect
|
sortable_multiselect |
|---|---|---|
| 複数選択 | ✅ | ✅ |
| 順番の制御 | ❌ | ✅ |
| アイコン表示 | ❌ | ✅ |
| 色のカスタマイズ | ❌ | ✅ |
| 最大選択数の制限 | ❌ | ✅ |
優先度リスト・カスタムランキング・手順の並べ替えなど、順番に意味がある場面でぜひ活用してみてください。
特に Streamlit は、社内ツールや試作アプリを短期間で作る場面で使われることが多いため、「少ないコードで操作しやすい UI を追加できる」価値は大きいです。sortable_multiselect は、その中でも 順位付き入力 というニッチですが実務でよく出る要件をうまく埋めてくれるコンポーネントだと感じます。
まずは文字列リストだけの最小構成から試してみて、必要に応じて show_numbers、order_colors、max_selections を足していくのがおすすめです。


