Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
管理画面向けUIコンポーネントの設計 - Web componentsでフレームワーク非依存を目指す
Search
LINEヤフーTech (LY Corporation Tech)
PRO
December 12, 2023
Technology
910
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
管理画面向けUIコンポーネントの設計 - Web componentsでフレームワーク非依存を目指す
「UIT × Bonfire Front-end Meetup #1」での発表資料です。
https://uit.connpass.com/event/300284/
LINEヤフーTech (LY Corporation Tech)
PRO
December 12, 2023
More Decks by LINEヤフーTech (LY Corporation Tech)
See All by LINEヤフーTech (LY Corporation Tech)
Community Over Code Glasgow 2026 + Lakehouse Day recap
lycorptech_jp
PRO
1
44
LLMをConfidential VMで動かす話
lycorptech_jp
PRO
0
80
Scaling Beyond the Exabyte: Lessons from Hadoop Integration and Operations at LY Corporation
lycorptech_jp
PRO
0
130
多層防御と最⼩権限で実現する、安全なAIエージェント設計パターン
lycorptech_jp
PRO
1
390
PM領域でのAI Agentの活用
lycorptech_jp
PRO
0
370
AI駆動開発を組織で促すために
lycorptech_jp
PRO
7
10k
検索技術知識0のエンジニアが広告検索システムを内製化して運用するまで
lycorptech_jp
PRO
1
480
No More Log Digging 〜AIを一次調査係にする アラートレビュー改善〜
lycorptech_jp
PRO
0
310
実践!既存 Project への AI-Driven Development 適用〜一ヶ月で Project 唯一のフロントエンドエンジニアを作り出せ〜
lycorptech_jp
PRO
1
570
Other Decks in Technology
See All in Technology
AI時代の組織作り:チーム開発から「個人×AI」への移行と、持続可能な「開発資本」の築き方
ham0215
1
270
re:Invent2026 事前勉強会 歴史と愉しみ方10分LT編
toshi_atsumi
0
150
Building Audio Plugin Ecosystem for Android in 2026
atsushieno
2
150
kintoneで在庫管理システムを作るときの要件定義・設計ポイント
kai0707
0
280
リアクションエンジニア ― 小さなリアクションから、話しかけやすい組織をつくる ―
ryuguyana
1
130
AI Agent 時代のデータ基盤: ClickHouse で実現する 超高速分析とコスト削減の両立
jozono
0
200
視野はAIに、視座は人に / ai-for-breadth-humans-for-perspective
nkzn
6
3.1k
Active Directory と Entra ID のむむむな関係
murachiakira
PRO
3
1.7k
Deep Data Security 機能解説
oracle4engineer
PRO
3
1k
試験勉強はGrokBotでやれ
maigo999
0
110
[dbts2026]数十PBの超巨大データ×AI活用を支えるSnowflakeの実力〜大規模環境におけるアーキテクチャと運用のリアル〜
y_matsubara
0
100
2026 Apache Flink Community Checkpoint
rmetzger
0
190
Featured
See All Featured
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.6k
Large-scale JavaScript Application Architecture
addyosmani
516
110k
Context Engineering - Making Every Token Count
addyosmani
9
1.3k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
48k
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.6k
Rails Girls Zürich Keynote
gr2m
96
14k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
68
60k
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
470
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
590
Between Models and Reality
mayunak
4
560
Designing Powerful Visuals for Engaging Learning
tmiket
1
650
Transcript
ཧը໘͚6*ίϯϙʔωϯτͷઃܭ 8FCDPNQPOFOUTͰϑϨʔϜϫʔΫඇґଘΛࢦ͢ 6*5ʷ#PO fi SF'SPOUFOE.FFUVQWPM "LJIJSP5BNBEB !TQSJOHSBJOJOH
"HFOEB طଘϓϩδΣΫτͷ$44ϑϨʔϜϫʔΫಋ ೖͷ͠͞ 8FCDPNQPOFOUTΛͬͨ6*ίϯϙʔω ϯτ࣮
"HFOEB طଘϓϩδΣΫτͷ$44ϑϨʔϜϫʔΫಋ ೖͷ͠͞ 8FCDPNQPOFOUTΛͬͨ6*ίϯϙʔω ϯτ࣮ ͕࣌ؒͳ͗͢͞ΔͷͰͪ͜ΒΛத৺ʹ͠·͢
ϓϩμΫτ w -*/&ެࣜΞΧϯτͷཧը໘ w 8FCͱJ04"OESPJE"QQ͚ʹϦϦʔε w ࣾһਓ ΞϧόΠτਓ 7/ ,3νʔϜͰ։ൃ
ཧը໘ͷ։ൃͷಛ w ͦΕͳΓʹେن w ߦ7VFϑΝΠϧ ݸ+4ϑΝΠϧ ݸ w ػೳ͕ଟذʹΘͨΔ͕ɺ֤ػೳͷར༻ස·ͪ·ͪ
w ಛఆͷϢʔβʔʹ͚ͩඞཁͳཧը໘͕ͨ͘͞Μ͋ΔΠϝʔδ ࠷খͷ࿑ྗͰɺͦͷը໘ͷॏཁʹ߹Θͤͨ ΫΦϦςΟͰ6*Λ࣮͢Δ͜ͱΛॏࢹ
ཧը໘ͷ6*ϥΠϒϥϦ w #PPUTUSBQΛΧελϚΠζͨ͠ಠࣗϥΠϒϥϦ w #PPUTUSBQաڈͷϥΠϒϥϦͱࢥΘΕ͍ͯΔ͕ʜ w ͋Δఔͬͨ6*Λ؆୯ʹ͑Δ w ΄΅ $44ͷΈͰߏ͞Ε࣮ͨͰɺͲͷΑ͏ͳڥͰ͑Δ
Ͱ#PPUTUSBQΛ͍ଓ͚Δ͔ʁ w ʮͳ͑͘Δʯ͜ͱ͕᠘ w Ҡߦͷ༏ઌΛԼ͛ͨ݁Ռɺগͣͭ͠$44ϑϨʔϜϫʔΫͷґଘ ΛਂΊ͍ͯ͘ w ཁ݅ʹ߹Θͤͯ$44ͷύον͕૿͍͖͑ͯɺՃతʹมߋΛࠔ ʹ͍ͯͨ͠
ҠߦͷऔΓΈ w ݕ౼ͷ݁Ռ5BJMXJOEΛ࠾༻͠ɺঃʑʹҠߦ͍ͯ͘͜͠ͱʹ w #PPUTUSBQͷDMBTT໊͕5BJMXJOEͷͷͱॏෳ😩 w Ήͳ͘5BJMXJOEͷQSF fi YΛ༗ޮԽ AMEAΛ༩
<div class="ld-flex ld-items-start ld-mx-200 ld-my-600"> <div class="ld-w-[130px] ld-h-[130px] ld-bg-gray-200"> <img class="ld-max-w-full ld-max-h-full" /> ...
6*ίϯϙʔωϯτͷ࣮ w 5BJMXJOEl6UJMJUZ fi STUzͳ$44ϑϨʔϜϫʔΫͳͷͰɺશʹ #PPUTUSBQΛஔ͖͑Δʹ6*ίϯϙʔωϯτΛ༻ҙ͢Δඞཁ͕͋Δ w ௨ৗͰ͋ΕͦΕͧΕͷϑϨʔϜϫʔΫ্Ͱಈ࡞͢Δίϯϙʔωϯτ ͱ࣮͍͕ͯͯ͘͠͠ʜ
͞Βʹঢ়گ͕ෳࡶʹͳ͍ͬͯ͘ w ࣮ಉ࣌ʹ7VF͔Β7VFͷҠߦ͕ਐߦத w ཧը໘ͷେ౷Ұܭը w ࠓޙʮ-*/&ެࣜΞΧϯτʯҎ֎ͷ༷ʑͳཧը໘ͷ6*69Λڞ ௨Խ͢ΔՄೳੑ w ϑϨʔϜϫʔΫ͢ΒόϥόϥʹͳΔՄೳੑ͕ग़͖ͯͨ
ϑϨʔϜϫʔΫʹґଘͤͣಈ࡞͢Δ6*ίϯϙʔωϯτ͕ඞཁ
͜Ε·Ͱͷ·ͱΊ w #PPUTUSBQ͋ΔఔͬͨϖʔδΛ࡞Δͷʹ͕͘ɺཁ͕݅ෳࡶʹ ͳΔʹͭΕͯύον͕૿͍͖͑ͯมߋΛࠔʹ͍ͯͬͨ͠ w 5BJMXJOE༏ल͕ͩ୯ମ͚ͩͰ#PPUTUSBQͷସʹͳΒͳ͍ w 7VF7VF 3FBDU ͰҰ؏ͯ͠ಈ࡞͢Δ6*ίϯϙʔωϯτΛ
ఏڙ͍ͨ͠
8FCDPNQPOFOUT
ͳͥ8FCDPNQPOFOUTʁ w ϑϨʔϜϫʔΫʹґଘ͠ͳ͍6*ίϯϙʔωϯτΛఏڙͰ͖Δ w 4IBEPX%0.ʹΑΔελΠϧͷʹΑΓɺ$44ͷΈͷϑϨʔϜ ϫʔΫʹ͕͋ͬͨղফͰ͖Δ
ͱ͍͏ͷͷʜ w 6*ίϯϙʔωϯτͱͯ͠8FCDPNQPOFOUTΛ࠾༻͢Δ͜ͱʹջٙత ͳҙݟଟ͍ w ։ൃύϥμΠϜͷҧ͍ w طଘϑϨʔϜϫʔΫͱͷੑ w 443ͷରԠ
w ͦΕͧΕͷ՝ʹ͍ͭͯɺࢲͨͪͷࠓͷղܾࡦΛ͠·͢
8FCDPNQPOFOUTͷ։ൃํ๏ w ֤ίϯϙʔωϯτ-JUΛ࣮ͬͯ w -JU&MFNFOU)5.-&MFNFOUͷ4VCDMBTTͱͯ͠ಈ࡞͠ɺಁաతʹ 8FCDPNQPOFOUTͷ"1*Λѻ͑Δ͕ಛ w ҰํͰɺ$MBTTϕʔεͷ"1*ݱͷϑϩϯτΤϯυ։ൃ͔Βͷίϯ ςΩετεΠονΛඞཁͱ͢Δ w
ಛʹ.JYJOؔ࿈Ͱ5ZQF4DSJQUͷରԠ͕ݫ͍͠
;BH
;BH w 6*ίϯϙʔωϯτ࣮ͷͨΊͷϥΠϒϥϦ w ϔουϨε6*ϥΠϒϥϦͷ"SLɺ$44JO+4ϑϨʔϜϫʔΫͷ 1BOEB$44͕;BHΛϕʔεʹ࣮͞Ε͍ͯΔ w ϑϨʔϜϫʔΫʹґଘ͠ͳ͍࣮ʹͳ͓ͬͯΓɺެࣜͰ3FBDU7VF 4PMJEʹରԠ 8FCDPNQPOFOUT
-JU ʹରԠՄೳ
-JU͚ͷϔϧύʔΛ༻ҙ͢Δ͜ͱͰͳ͘ಈ࡞ import * as checkbox from '@zag-js/checkbox'; import { useController
} from 'haunted'; import { html } from 'lit'; import { MachineController, applyProps, createElement } from '~util'; export const Checkbox = createElement((element) => { const machine = useController( (host) => new MachineController(host, checkbox) ); const api = machine.connect(); return html` <label ${applyProps(api.rootProps)}> <div class="checkbox" ${applyProps(api.controlProps)}></div> <input ${applyProps(api.hiddenInputProps)} /> <span ${applyProps(api.labelProps)}> <slot></slot> </span> </label> `; });
;BHͷڧΈ w εςʔτϚγϯΛ༻ҙ͢Δ͜ͱͰɺঢ়ଶཧʹؔ͢ΔॲཧΛۃݶ·Ͱ நԽͰ͖Δ w ผ్$44JO+4Λఏڙ͢Δڥ͕༻ҙͰ͖Εɺ;Δ·͍Λҡ࣋͠ ͨ··8FCDPNQPOFOUT͔Β٫͢Δ͜ͱ͢ΒՄೳ w 8FCDPNQPOFOUϑϨʔϜϫʔΫʹґଘ࣮͔ͨ͠Β٫Ͱ͖Δ
طଘϑϨʔϜϫʔΫͱͷੑ w 8FCDPNQPOFOUT୯ͳΔ)5.-λάͱͯ͠Ͳ͜ͰͰ͑Δ͕ɺ ٯʹܽͰ͋Δ w 3FBDU7VFͷίϯϙʔωϯτͱͯ͑ͣ͠ɺ5ZQF4DSJQUͷܕ͕ޮ͔ ͳ͍ w -JU4UFODJMͳͲϑϨʔϜϫʔΫผʹϥούʔίϯϙʔωϯτΛग़ྗ ͢Δػೳ͕༻ҙ͞Ε͍ͯΔ
DVTUPNFMFNFOUTNBOJGFTU w ੜπʔϧ͕όϥόϥʹ࣮͞Ε͍ͯΔ͜ͱΛࢹͯ͠࡞ΒΕͨɺ $VTUPNFMFNFOUͷϚχϑΣετϑΝΠϧͷ༷ w ADVTUPNFMFNFOUTKTPOAͱ͍͏໊લͷ+40/4DIFNBΛ༻ҙ ͠ɺͦͷதͰ$VTUPNFMFNFOUʹ͍ͭͯͷϝλσʔλΛએݴ͢Δ $VTUPNFMFNFOUTNBOJGFTUΛͱʹ 3FBDU7VF͚ϥούʔΛੜ
ιʔείʔυ͔ΒQSPQTTMPUTFNJUTͷܕΛநग़ import { defineComponentEmits, defineComponentProps, defineComponentSlots, } from '~util'; export
const tagName = 'my-checkbox'; export const props = defineComponentProps<{ checked: boolean; }>({ checked: false, }); export const slots = defineComponentSlots<{ default: () => void; }>(); export const emit = defineComponentEmits<{ changed: boolean | 'indeterminate'; }>(); { "schemaVersion": "1.0.0", "modules": [ { "kind": "javascript-module", "declarations": [ { "kind": "class", "customElement": true, "tagName": "my-checkbox", "attributes": [ { "name": "checked", "fieldName": "checked", "type": { "text": "boolean" }, "default": "false" } ], "slots": [], "events": [ { "name": "changed", "type": { "text": "CustomEvent<boolean | \"indeterminate\">" }
ͳ͘3FBDU7VF͔Βར༻Ͱ͖ΔΑ͏ʹʂ <MyCheckbox :checked="checked" @changed="..."> ... </MyCheckbox> <MyCheckbox checked={checked} onChanged={...}> ...
</MyCheckbox> { "schemaVersion": "1.0.0", "modules": [ { "kind": "javascript-module", "declarations": [ { "kind": "class", "customElement": true, "tagName": "my-checkbox", "attributes": [ { "name": "checked", "fieldName": "checked", "type": { "text": "boolean" }, "default": "false" } ], "slots": [], "events": [ { "name": "changed", "type": { "text": "CustomEvent<boolean | \"indeterminate\">" } 7VF 3FBDU
443ͷରԠ w ೦ͳ͕Βɺ443Λ࣮ݱ͢ΔͨΊͷΤίγεςϜ·ͩ·ͩ w ࢲͨͪͷϓϩμΫτ͕443Λ༻͍ͯ͠ͳ͔ͬͨ8FC DPNQPOFOUTΛ࠾༻ͨ͠ཧ༝ͷҰͭ
%FDMBSBUJWF4IBEPX%0.ͷظ w ͔͠͠ʜʜ%FDMBSBUJWF4IBEPX%0.͕͍ͭʹ4BGBSJʹʂ w 443ڥͰ4IBEPX%0.Λར༻͢ΔͨΊͷٕज़ཁૉ w खݩͰࢼ͢ൣғͰɺ)ZESBUJPOFSSPS͕ൃੜ͢Δͷͷɺͳ͘ ίϯϙʔωϯτ͕443)ZESBUJPO͞ΕΔঢ়ଶͩͬͨ /FYUKT /VYU
$PODMVTJPO w 8FCDPNQPOFOUTϑϨʔϜϫʔΫඇґଘ ͷ6*ίϯϙʔωϯτΛ࣮͢Δͷʹྑ͍બ w ;BHʹΑΔ6*ͷ;Δ·͍ͷ w কདྷੑΛߟ͑ͨΤεέʔϓϋον͕ॏཁ