Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
UIパーツの設計を「型」から読み解く 〜TSKaigiのセッションから得た学び〜
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
yud0uhu
June 25, 2026
Technology
390
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
UIパーツの設計を「型」から読み解く 〜TSKaigiのセッションから得た学び〜
TSKaigi 2026事後勉強会の登壇資料です。
https://smarthr.connpass.com/event/392342/
yud0uhu
June 25, 2026
More Decks by yud0uhu
See All by yud0uhu
美しいコードを書くためにF#を学んでみた話
yud0uhu
1
500
未必のマクベス
yud0uhu
0
48
Webブラウザ向け動画配信プレイヤーの 大規模リプレイスから得た知見と学び
yud0uhu
0
400
早朝の渋谷の青さ、あるいは溺れた人を助ける為に飛び込んだ海の向こう側に見る、自己覚知と自己開示の尊さ
yud0uhu
1
1k
動画配信サービスのフロントエンド実装に学ぶ設計原則
yud0uhu
1
400
非デザイナーのフロントエンドエンジニアがOOUIを考える
yud0uhu
9
6k
2023年の ゼロランタイムCSS in JS⚡️ を考える
yud0uhu
5
5.1k
Vue3/Electronで自作したマークダウンエディタをVue3/Tauriにリプレイスした話
yud0uhu
2
3.2k
入社半年を迎える新米エンジニアがカンファレンス・勉強会から得た学び
yud0uhu
0
1.1k
Other Decks in Technology
See All in Technology
Flutterをカメラで動かしたかった話
sony
1
130
強化学習「理論」入門
enakai00
3
3.6k
侵入は突然に 〜 IoTマルウェアと悪用される家庭の機器 ~ / When Intrusion Strikes: IoT Malware and the Abuse of Home Devices
nttcom
0
1.5k
第3回しろおびセキュリティスポンサーセッション
log0417
0
150
[MIRU26] Open-Vocabulary Intention-Guided Object Detection in Diverse Scenes
keio_smilab
PRO
0
140
OSPN.JPバージョンアップ作業進捗のご報告 / 20260801-osc26kyoto
akkiesoft
0
320
え?フロントエンドエンジニアの ワイがインフラも!?
puku0x
1
360
FORENSIA: ローカルLLMフォレンジックハーネス
sumeshi
2
230
グローバル基準のSREは、運用現場でどう機能したか:成熟度アセスメントの実践 / SRE NEXT 2026
sorawatanabe
0
110
Eight Engineering Unit 紹介資料
sansan33
PRO
3
8.1k
Invisible to AI? Making TYPO3 Sites Quotable by AI Search Systems
wolfgangwagner
0
140
【CEDEC2026】『GRANBLUE FANTASY: Relink - Endless Ragnarok』のバトル制作事例 ~最高のキャラゲーを目指して~
cygames
PRO
0
210
Featured
See All Featured
Rails Girls Zürich Keynote
gr2m
96
14k
We Have a Design System, Now What?
morganepeng
55
8.3k
Navigating Weather and Climate Data
rabernat
0
450
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
330
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
610
Visualization
eitanlees
152
17k
Darren the Foodie - Storyboard
khoart
PRO
3
3.5k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
830
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
360
Building Applications with DynamoDB
mza
96
7.2k
Designing for Timeless Needs
cassininazir
1
430
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Transcript
UIパーツの設計を「型」から読み解く 〜TSKaigiのセッションから得た学び〜 0yu @yud0uhu 2026/06/25(Thu) TSKaigi 2026事後勉強会
自己紹介 0yu(おゆ) Web FE 好きなもの 推理小説、映画、謎解き・マダミス、ウイスキー @yud0uhu @yud0uhu
TSKaigiのセッションから得た学び
出典:React の props は値の集合ではない — UI の状態を宣言するコンポーネント設計(nabeliwo)さん
TSKaigiのセッションから得た学び UIパーツの設計を「型」から読み解く 同セッションの具体例として挙げられていた状態
出典:「進研ゼミでやったところだ!」現象|西川智希. note. https://note.com/nishikooooth/n/n9727b86bd772
様々な状態を持つUIパーツを propsで表現する
様々な状態を持つアイコンをpropsで表現する 課題 用途に応じて様々な状態を表現する「AnimationIcon」を再設計したい 「ToggleIcon」の名前で共通化された「AnimationIcon」が存在する お気に入り(オン/オフ) 再生/停止 ミュート/解除 10秒戻す、10秒進める
様々な状態を持つアイコンをpropsで表現する アイコンの責務と状態(振る舞い)の整理 すべてのアイコンに共通する振る舞い 「押下したこと」がアニメーションとしてフィードバックされる アイコンごとに異なる振る舞い トグルするアイコン(押下するとアイコンが変わる) 例:お気に入り(オン/オフ)、再生/停止、ミュート/解除 トグルしないアイコン(押下してもアイコンは変わらない) 例:10秒戻す、10秒進める
Before
Before Before 1 2 3 4 5 6 7 8
9 10 11 // 「トグルするアイコン」と // 「トグルしないアイコン」の責務が混在している type Props = { isShrinking: boolean; iconComponent: React.ReactNode; // トグルアイコンなのに、トグルしないアイコンが存在する previousIconComponent?: React.ReactNode; // アニメーションをさせるためだけに存在する handleShrinkComplete: () => void; handleGrowComplete: () => void; };
Before リファクタ前のコードの持つ問題点 「コード(型)が仕様を表現しきれていない」 実装者に誤った使い方を誘引してしまう
After
After 「discriminated union」でUIの振る舞いを型に閉じ込める 1 2 3 4 5 6 7
8 9 10 11 12 13 type ToggleProps = BaseProps & { type: "toggle"; isToggled: boolean; fromIcon: React.ReactNode; toIcon: React.ReactNode; }; type NonToggleProps = BaseProps & { type: "non-toggle"; icon: React.ReactNode; }; type Props = ToggleProps | NonToggleProps;
After Propsでアイコンごとの責務を分離する 1 2 3 4 5 6 7 8
9 export type BaseBouncyIconProps = { onClick: () => void; onAnimationEnd?: () => void; className?: string; }; export type PlayToPauseBouncyIconProps = BaseBouncyIconProps & { isPlaying: boolean; };
After JSXの構造でUIの状態を表現する 1 2 3 4 5 6 7 8
9 10 11 12 type ToggleProps = BaseProps & { // ... fromIcon: React.ReactNode; toIcon: React.ReactNode; }; return ( <BaseBouncyIconButton // ... fromIcon={<IconPlay className="size-full" />} toIcon={<IconPause className="size-full" />} />
「discriminated union」で UIの振る舞いを型に閉じ込める
「discriminated union」でUIの振る舞いを型に閉じ込める 「discriminated union」でUIの振る舞いを型に閉じ込める 1 2 3 4 5 6
7 8 9 10 11 12 // 不可能な状態を許容してしまう type BadProgressBarProps = { status: 'loading' | 'success' | 'error'; percent?: number; // loadingの時だけほしい message?: string; // errorの時だけほしい }; // 判別可能なユニオン型 type GoodProgressBarProps = | { status: 'loading'; percent: number; } | { status: 'error'; message: string; } | { status: 'success'; };
「シンプル」が至上
「シンプル」が至上 「シンプル」が至上 「いかに削ぎ落とすか、公開するものを減らすか」を考える ex.「判別可能なユニオン型」によるカプセル化でスコープを閉じる アニメーションする責務が外側から介在しなくなる
オブジェクト指向から考える 「カプセル化」と「命名」
オブジェクト指向から考える「カプセル化」と「命名」 オブジェクト指向から考える「カプセル化」と「命名」 “オブジェクト指向を超えて重要な原則は 「カプセル化」と「正しい名前付け」” ➖ オブジェクト指向と10年戦ってわかったこと | https://qiita.com/tutinoco/items/6952b01e5fc38914ec4e
オブジェクト指向から考える「カプセル化」と「命名」 オブジェクト指向から考える「カプセル化」と「命名」 「discriminated union」による「カプセル化」 単にPropsを共通化するのではなく、UIの振る舞い(ドメイン)を正し く型に落とし込む(モデリングする) 不可能な状態を型で許容しない 「正しい名前付け」による「関心の分離」 「アニメーションという振る舞い」と 「トグルする/しないというロジック」を分離して考える
ToggleIconはToggleIconではなかった
オブジェクト指向から考える「カプセル化」と「命名」 オブジェクト指向から考える「カプセル化」と「命名」 「discriminated union」による「カプセル化」 単にPropsを共通化するのではなく、UIの振る舞い(ドメイン)を正し く型に落とし込む(モデリングする) 不可能な状態を型で許容しない 「正しい名前付け」による「関心の分離」 「アニメーションという振る舞い」と 「トグルする/しないというロジック」を分離して考える
ToggleIconはToggleIconではなかった
まとめ
まとめ まとめ UIコンポーネントの設計では、Propsのデータ型そのもので仕様(UIの振 る舞い)を表現し、使う側の認知負荷を減らすのが理想 UIごとの責務の分離と、「引き算」を意識する 実業務で先輩から学んだ設計の話とセッションの内容が重なり、ユース ケース的な学びが大きかった💪