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コンポーネントの設計 - Web componentsでフレームワーク非依存を目指す
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
LINEヤフーTech (LY Corporation Tech)
PRO
December 12, 2023
Technology
830
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)
Business ID Integration at LY Corporation : Phased Migration for a B2B authentication platform with Tens of Millions of Users
lycorptech_jp
PRO
0
11
LINE Messaging: From Active-Standby to Active-Active Multi-DC Architecture
lycorptech_jp
PRO
0
18
LY Corporation's implementation of Confidential VM ensuring privacy for AI features
lycorptech_jp
PRO
0
23
Good Design Pays Dividends: The Evolution of LINE API Gateway Handling 30B Daily Requests
lycorptech_jp
PRO
0
20
The Path Paved by Flava MCP Hub Piping Work for the AI Era
lycorptech_jp
PRO
0
11
The Kitakyushu Data Center's Unrelenting Effort to Reduce Air Cooling Power Consumption
lycorptech_jp
PRO
0
13
Designing a Media Content Ecosystem — Case Studies on Integrating AI-Generated Content
lycorptech_jp
PRO
0
31
Beyond Intelligence to Safety: The Ultimate Guide to 'External AI Guardrails' in the AI Era
lycorptech_jp
PRO
0
15
Why Doesn’t AI Reduce the Workload as Much as Expected? : The Limits of Human-in-the-Loop and AI-Ready Workflow Design
lycorptech_jp
PRO
0
11
Other Decks in Technology
See All in Technology
FPGAの開発コンペでZephyrを使ってみた
iotengineer22
0
180
Claude Codeをどのように キャッチアップしているか
oikon48
13
8.8k
生成 AI 実践ガイド (概略版) AIガバナンス編
asei
0
180
事業会社における 機械学習・推薦システム技術の活用事例と必要な能力 / ml-recsys-in-layerx-wantedly-2026
yuya4
0
160
いまさら聞けない「仕様駆動開発入門」 〜AI活用時代の開発プロセスを考える〜
findy_eventslides
2
180
SONiCのNETCONFサーバ機能を試してみた
sonic
0
110
Kiro Ambassador を目指す話
k_adachi_01
0
120
技術・能力を向上する原理原則 #きのこセッションa #きのこ2026
bash0c7
0
110
「勝手に広まる」人気 AI エージェントを爆速で作ろう!(AWS Summit Japan 2026講演資料)
minorun365
PRO
10
2.4k
AIのReact習熟度を測る
uhyo
2
670
Oracle AI Database@Azure:サービス概要のご紹介
oracle4engineer
PRO
6
2k
WebGIS AI Agentの紹介
_shimizu
0
530
Featured
See All Featured
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
400
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
200
Believing is Seeing
oripsolob
1
150
We Are The Robots
honzajavorek
0
250
Skip the Path - Find Your Career Trail
mkilby
1
150
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
140
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
200
First, design no harm
axbom
PRO
2
1.2k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
270
Crafting Experiences
bethany
1
190
Typedesign – Prime Four
hannesfritz
42
3.1k
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 কདྷੑΛߟ͑ͨΤεέʔϓϋον͕ॏཁ