コンポーネント工房:Reflexライブラリ100
·
講座の概要
レイアウト
·
Box
·
Flex
·
Stack
·
Grid
·
Container
·
Section
·
Center
·
Spacer
·
Separator
·
Card
·
Inset
·
Aspect Ratio
·
Fragment
タイポグラフィ
·
Text
·
Heading
·
Link
·
Code
·
Markdown
·
Blockquote
·
Quote
·
Strong
·
Em
·
Kbd
フォーム
·
Button
·
Input
·
Text Area
·
Checkbox
·
Switch
·
Radio Group
·
Select
·
Slider
·
Form
·
Upload
データ表示
·
Badge
·
Avatar
·
Icon
·
Callout
·
List
·
Data List
·
Code Block
·
Progress
·
Spinner
·
Scroll Area
·
Moment
開閉と切り替え
·
Tabs
·
Accordion
·
Segmented Control
オーバーレイ
·
Tooltip
·
Popover
·
Hover Card
·
Dialog
·
Alert Dialog
·
Drawer
·
Dropdown Menu
·
Context Menu
·
Toast
動的レンダリング
·
Cond
·
Match
·
Foreach
·
Auto Scroll
メディア
·
Image
·
Audio
·
Video
表とデータグリッド
·
Table
·
Data Table
·
Data Editor
チャート
·
Area Chart
·
Bar Chart
·
Line Chart
·
Composed Chart
·
Pie Chart
·
Radar Chart
·
Radial Bar Chart
·
Scatter Chart
·
Funnel Chart
·
Treemap
·
Sankey Chart
·
Error Bar
チャートの部品
·
Axis
·
Cartesian Grid
·
Chart Tooltip
·
Legend
·
Label
·
Reference
·
Brush
ほかのチャートライブラリ
·
Plotly
·
Pyplot
HTML要素
·
HTML
·
HTML Text
·
HTML Layout
·
HTML Forms
·
HTML Media
·
HTML Tables
·
SVG
そのほかの道具
·
Theme
·
Skeleton
·
Clipboard
·
Html Embed
·
Script
·
Memo
rx.clipboard公式ドキュメント
工房の注文書
バグ報告のフォームに、ユーザーがスクリーンショットを貼り付けるだけですぐ画像が添付される欄を作ってください。
rx.clipboardは貼り付け(paste)イベントを受け取り、貼り付けた内容を種類ごとに State に渡します。テキストだけでなく、画像のようなバイナリデータも受け取ります。
画面には何も描かない透明なコンポーネントで、包んだ子要素で起きた貼り付けを聞き取ります。Reflex 0.5.6 から入っています。
class ClipboardBasicState(rx.State):
items: list[str] = []
@rx.event
def on_paste(self, data: list[tuple[str, str]]):
self.items = [f"{mime_type}: {item[:60]}" for mime_type, item in data]
rx.vstack(
rx.clipboard(
rx.input(placeholder="Copy some text, then paste here"),
on_paste=ClipboardBasicState.on_paste,
),
rx.foreach(ClipboardBasicState.items, lambda line: rx.code(line, size="1")),
width="100%",
max_width="420px",
)rx.clipboardには目に見えるプロパティがないので、実習台の代わりに貼り付けに反応する例で見ていきます。
テキストを貼るとtext/plain、Web ページからコピーした文章を貼るとtext/htmlも一緒に、画像を貼るとimage/pngのような種類が入ってきます。
Paste events: 0
class ClipboardTypesState(rx.State):
count: int = 0
types: list[str] = []
@rx.event
def on_paste(self, data: list[tuple[str, str]]):
self.count += 1
self.types = [mime_type for mime_type, _ in data]
rx.card(
rx.clipboard(
rx.text_area(placeholder="Paste text, an image, or a copied web page", rows="3"),
on_paste=ClipboardTypesState.on_paste,
),
rx.text("Paste events: ", ClipboardTypesState.count, size="2", margin_top="8px"),
rx.flex(rx.foreach(ClipboardTypesState.types, lambda t: rx.badge(t)), spacing="2", wrap="wrap", margin_top="6px"),
max_width="420px",
)| プロパティ | 値 | 既定値 | 用途 |
|---|---|---|---|
on_paste | イベントハンドラー | なし | (MIME の種類, データ)タプルのリストを受け取る |
targets | 要素のidのリスト | 子要素、子要素がなければ文書全体 | 貼り付けを聞き取る要素 |
.stop_propagation | イベントアクション | なし | 外側の貼り付け処理に伝わらないようにする |
.prevent_default | イベントアクション | なし | 入力欄に実際に貼り付けられる既定の動作を止める |
on_pasteが受け取るdataは(mime_type, data)タプルのリストです。テキストはそのまま文字列で届き、
画像のようなバイナリデータは base64 でエンコードされた data URI(data:image/png;base64,...)で届きます。この文字列はrx.imageのsrcにそのまま入れられ、
サーバーでバイト列が必要なら、Python のurllib.request.urlopen(data_uri).read()で戻せます。
子要素なしでrx.clipboard()だけを置くと文書のpasteイベントに付くので、ページのどこに貼り付けても実行されます。
このページでそうすると、ほかの例の貼り付けまですべて拾ってしまうので、公式ドキュメントの例をコードとしてだけ示します。
class ClipboardPasteState(rx.State):
@rx.event
def on_paste(self, data: list[tuple[str, str]]):
for mime_type, item in data:
yield rx.toast(f"Pasted {mime_type} data: {item}")
def clipboard_example():
return rx.fragment(
rx.clipboard(on_paste=ClipboardPasteState.on_paste), # no children: listens for paste on the whole document
"Paste Content Here",
)特定の要素でだけ貼り付けを受け取るなら、rx.clipboardでその要素を包みます。外側にページ全体の処理があるなら、.stop_propagationでイベントが上に伝わらないようにします。
.prevent_defaultを付けると、入力欄に文字が実際には貼り付けられません。2つ目の入力欄に文章を貼ってみると、欄は空のままです。
No image yet. Copy an image (or take a screenshot) and paste above.
class ClipboardImageState(rx.State):
last_image_uri: str = ""
@rx.event
def on_paste(self, data: list[tuple[str, str]]):
for mime_type, item in data:
if mime_type.startswith("image/"):
if len(item) > 2_000_000:
return rx.toast("This image is too large for the demo")
self.last_image_uri = item
break
else:
return rx.toast("Did not find an image in the pasted data")
rx.vstack(
rx.clipboard(
rx.input(placeholder="Paste Image (stop propagation)"),
on_paste=ClipboardImageState.on_paste.stop_propagation,
),
rx.clipboard(
rx.input(placeholder="Paste Image (prevent default)"),
on_paste=ClipboardImageState.on_paste.prevent_default,
),
rx.cond(
ClipboardImageState.last_image_uri != "",
rx.image(src=ClipboardImageState.last_image_uri, alt="Image pasted from clipboard", max_width="240px", border_radius="6px"),
rx.text("No image yet. Copy an image (or take a screenshot) and paste above.", size="2", color_scheme="gray"),
),
width="100%",
max_width="420px",
)targetsに要素のidを渡すと、包まなくてもその要素だけを聞き取ります。子要素を包むときは、Reflex が子要素にidを付けてtargetsを自動で埋めます。
Pasted characters: 0
class ClipboardTargetState(rx.State):
pasted_chars: int = 0
@rx.event
def on_paste(self, data: list[tuple[str, str]]):
self.pasted_chars += sum(len(item) for mime_type, item in data if mime_type == "text/plain")
rx.vstack(
rx.clipboard(on_paste=ClipboardTargetState.on_paste, targets=["clipboard_target_note"]),
rx.text_area(id="clipboard_target_note", placeholder="Only this box is watched", rows="2"),
rx.input(placeholder="This box is not watched"),
rx.text("Pasted characters: ", ClipboardTargetState.pasted_chars, size="2"),
width="100%",
max_width="420px",
)点線のボックスをクリックしてフォーカスしてからスクリーンショットを貼ると、画像が添付されます。ボックスは入力欄ではないのでtab_index=0でフォーカスを受け取れるようにし、
.prevent_default.stop_propagationのようにイベントアクションをつなげました。画像は data URI として State に入るので、大きすぎる画像ははじきます。
Click here, then paste a screenshot (Ctrl + V)
class ClipboardTicketState(rx.State):
shot: str = ""
note: str = ""
@rx.event
def on_paste(self, data: list[tuple[str, str]]):
for mime_type, item in data:
if mime_type.startswith("image/") and len(item) <= 2_000_000:
self.shot = item
return
return rx.toast("Paste a screenshot (an image) here")
@rx.event
def change_note(self, value: str):
self.note = value
@rx.event
def clear_shot(self):
self.shot = ""
rx.card(
rx.heading("Bug report", size="3"),
rx.text_area(
value=ClipboardTicketState.note,
on_change=ClipboardTicketState.change_note,
placeholder="What went wrong?",
rows="2",
margin_y="8px",
),
rx.clipboard(
rx.box(
rx.cond(
ClipboardTicketState.shot != "",
rx.image(src=ClipboardTicketState.shot, alt="Pasted screenshot", max_height="160px"),
rx.text("Click here, then paste a screenshot (Ctrl + V)", size="2", color_scheme="gray"),
),
tab_index=0,
padding="16px",
border=f"2px dashed {rx.color('gray', 7)}",
border_radius="8px",
text_align="center",
),
on_paste=ClipboardTicketState.on_paste.prevent_default.stop_propagation,
),
rx.button("Remove screenshot", on_click=ClipboardTicketState.clear_shot, variant="soft", color_scheme="gray", size="1", margin_top="8px"),
max_width="420px",
)工房ノート
rx.clipboard(子要素, on_paste=...) は子要素で起きた貼り付けを聞き取る。子要素がなければ文書全体。
on_paste は [(mime_type, data), ...] を受け取る。バイナリデータは base64 の data URI。
data URI は rx.image の src にそのまま使える。
.stop_propagation は外側の処理に伝えない、.prevent_default は実際の貼り付けを止める。
targets=[id, ...] で、包まずに特定の要素だけを聞き取る。
新しい授業・講座のお知らせを受け取る
この講座に授業が追加されたり、続きの講座が公開されたりしたらメールでお知らせします。
R
ReflexKR
触って学ぶPythonとReflex。すべての例はReflex 0.10.0で実際に動かして確認しています。
ReflexKRはバナー広告なし・無料で運営しています。役に立ったら、コーヒー一杯で応援してください。 ☕ コーヒーで応援する
アフィリエイトと支援について© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0
質問と回答
この回について気になることを書き込んでください。すべての言語のページの質問がここに集まります。