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
ピクシブのデザインシステム「Charcoal」アイコンライブラリをつくる
Search
mimo
September 29, 2023
1.4k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ピクシブのデザインシステム「Charcoal」アイコンライブラリをつくる
mimo
September 29, 2023
More Decks by mimo
See All by mimo
Figma REST APIからCSS変数を生成しよう
mimokmt
0
1.5k
Featured
See All Featured
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
560
Google's AI Overviews - The New Search
badams
0
1.6k
Building Applications with DynamoDB
mza
96
7.2k
Darren the Foodie - Storyboard
khoart
PRO
4
4k
How STYLIGHT went responsive
nonsquared
100
6.3k
Site-Speed That Sticks
csswizardry
13
1.5k
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
260
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
570
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Building Flexible Design Systems
yeseniaperezcruz
330
41k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.7k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
390
Transcript
pixiv.inc ピクシブのデザインシステム「Charcoal」 アイコンライブラリを つくる @mi2_okmt
Profile mimo フロントエンドエンジニア 2022年 新卒入社 CTO室デザインシステム部 兼 クリエイター事業部 FACTORY部 初音ミクが好き
DJする趣味がある
しゃべること • Charcoalとは? • charcoal-ui/iconsとは? • charcoal-ui/iconsをつくる • SVGのimportについて
とは?
とは? • pixivをはじめ、様々なプロダクトが利用 • web / iOS / Android それぞれに対応した実装がある
• 2022年7月からはデザインシステム部が開発してる ◦ DEV MEETUP(2020) のときはタスクフォースだった ◦ 部外からもドカドカPRをくれるのでレビューしてる ピクシブのデザインシステム「Charcoal」
• 10個のパッケージを持つweb実装のモノレポ • @charcoal-ui/styled, /tailwind-config, /react …などなど • 今回は @charcoal-ui/icons
について話します web実装 pixiv/charcoal とは?
@charcoal-ui/icons
@charcoal-ui/icons • Web Componentsとして実装 ◦ 他フレームワークへの依存なしで利用可能 ◦ Charcoalの他パッケージへの依存もほとんどない • SVGファイルを独自アイコンとして登録できる
Charcoalのアイコンライブラリ
@charcoal-ui/icons 1. yarn add @charcoal-ui/icons 2. import ‘@charcoal-ui/icons’ 3. <pixiv-icon
name=”16/Smile”> 簡単 3ステップ クイックスタート!
@charcoal-ui/icons パッケージの構造 Figma SVG stringをexportする JSのパッケージ @charcoal-ui/icon-files .cjs SVGを Custom
Elementsにする @charcoal-ui/icons jsでimport @charcoal-ui /icons-cli
@charcoal-ui/icons • Figma APIからSVGとしてアイコンを取得 • fill属性を currentcolor に置き換える • SVGをstringでexportするファイルをつくる
• /icon-files に差分があれば commit して PR をつくる Figmaのアイコンを取ってくる icons-cli
@charcoal-ui/icons • icons-cli によって作られる.cjsファイルのパッケージ • export default '<svg … だけがたくさん
• どうしてこうなったのかはあとで話します SVGタグをstringで返す icon-files
@charcoal-ui/icons • icon-filesに依存 SVG文字列をCustom Elementsにする • 指定されたSVGファイルをアイコンにする ◦ icon-files にないアイコンを使いたい需要に対応
◦ PixivIcon.extend() Custom Elementsをつくる icons
どうして Web Components?
どうしてWeb Components? • 2021年2月としては珍しい技術選択 • ピクシブに求められる要件がいくつかあった @charcoal-ui/iconsはWeb Components
どうしてWeb Components? • プロダクトごとに異なるフレームワーク ◦ Smarty ERB React Vue …
• 導入がスムーズに行えること • SSRできる • 検討したがボツになったものを具体的に紹介します ピクシブでの要件
@charcoal-ui/icons ボツ案
@charcoal-ui/icons ボツ案 1. Reactでつくる 2. icon font 3. SVGR ボツ案一覧
4. SVGのuseタグ 5. Lit HTML
@charcoal-ui/icons ボツ案 × Reactでしか使えない ピクシブにはVueプロダクトもある (BOOTH pixivのSP版 …など) × ReactプロダクトでもReactだけを使うとは限らない
局所的にSmartyやERBをなこともある 1. Reactでつくる
@charcoal-ui/icons ボツ案 × フォントをつくるのがめんどくさい × font familyの上書きで変な文字が出る × スクリーンリーダーやa11yに弱い <i>タグなどを本来と異なる用途で使うため
2. icon font
@charcoal-ui/icons ボツ案 SVGR: SVGをimportするとReactコンポーネントになるもの × inline SVGになって、HTMLが巨大になるおそれ JSXからのimportでHTMLが巨大になるリスクが指摘されていた × React前提になる
3. SVGRのようなアプローチ
@charcoal-ui/icons ボツ案 id のついているSVG要素を useタグで呼び出せる × どうやってアイコンファイルを配信するか不明 SVGアイコン全部入りファイルを読み込ませる必要がありそう × ロード時間や維持管理が厳しそう
4. SVGのuseタグ
@charcoal-ui/icons ボツ案 Web Componentsが作れる薄めなライブラリ ✓ いったん採用した × SSR対応のとき、Lit HTMLが嫌な実装だったので結局やめた 5.
Lit HTML
@charcoal-ui/icons ボツ案 × 内部でDOM APIをめっちゃさわる × SSRができない nodeでimportするとクラッシュした × lit-labs/ssr
があったが嫌な実装だった globalThisにDOM APIを生やすような感じ ここがいい感じだったら採用していたかもしれない... 5. Lit HTML
そして Web Components へ
そして Web Components へ ✓ 使うアイコンだけ読み込ませられる ✓ 特定のフレームワークに依存させることなく実装できる ✓ 無理のない実装方法である
ion-icon も Web Componentsだった SVGファイルをDOMにレンダリング
そして Web Components へ • 当時「Vue 3でWeb Components対応」と言われていた • SSR対応のCustom
Elementsの参考に実装 • globalThis に頼った箇所がひとつだけ残った ◦ HTMLElementsがSSRでundefinedになるのを回避させる部分 SSRでも動くコードで実装
できあがった @charcoal-ui/icons
できあがった @charcoal-ui/icons 👍 dependenciesがたった2つになった DOMPurifyとwarningsのみ 👍 最新でも、レガシーでも、CSRでも、SSRでも使える tailwindもstyledもReactもVueもいらない! 👍 社内プロダクトへの導入がスムーズだった
良かったこと
できあがった @charcoal-ui/icons 🥳< 属人化していて更新しづらくて不幸になってました。 ツールでサポートされたので属人性も手間もなくなり、 工数削減だけでなく参入もしやすくなりました。 喜びの声
🤔 PixivIcon.extends() を使うときはバンドラの設定が必要 独自アイコンを使うなら各自でバンドラを設定してね! 🤔 a11yが不十分 もし対応不可能なことがあるとマズい 🤔 レイアウトシフトが起こりやすい ドキュメントにリセットCSSを載せてるだけなのでパッケージに含めたい...
残された課題・デメリット できあがった @charcoal-ui/icons
SVGのimport
SVGのimport おさらい Figma SVG stringをexportする JSのパッケージ @charcoal-ui/icon-files .cjs SVGを Custom
Elementsにする @charcoal-ui/icons jsでimport @charcoal-ui /icons-cli
SVGのimport おさらい Figma SVG stringをexport するJSのパッケージ @charcoal-ui/icon-files .cjs SVGを Custom
Elementsにする @charcoal-ui/icons jsでimport @charcoal-ui /icons-cli
SVGのimport • 最近はwebpack以外のバンドラが増えた ◦ vite swc Parcel … • /icons
は webpack 環境下でしか動かなかった • 社内から webpack 以外でも動いてほしいとの要望が来た webpackが必須だった /icons v1.x.x
SVGのimport • 「.jsではないものを相対パスで読み込む」に差が出やすい なぜ webpack でしか動かなかったのか const { default: filepath
} = await import( `../svg/${encodeURIComponent(size)}/ ${encodeURIComponent(name)}.svg` ) • jsに従って文字列を扱えば解決するのでは?
SVGのimport • CIでやることを追加 ◦ icons-cli で SVGを取ってきてSVGファイルをつくる ◦ + SVGファイル
→ string を export する .cjs ファイル ◦ + 保存する場所を /icon-files に変更 ◦ つくったファイルをまとめてcommit v2.x.x から増えた /icon-files
SVGのimport • アイコンの import する処理を分離 ◦ SVG string 用の関数を用意 ◦
独自アイコン用に dynamic import する処理も残す ▪ PixivIcon.extends()にバンドラ設定が必要なのはこのため /icons の SVG import 改修
SVGのimport // v1.x.x const { default: filepath } = await
import( `../svg/${encodeURIComponent(size)}/ ${encodeURIComponent(name)}.svg` ) // v2.x.x import charcoalIconFiles from ‘@charcoal-ui/icon-files’ get importIconFile() { return charcoalIconFiles[this._name] }
今後の話
今後の話 • webpack以外でも使えることを確認すべき • 依存ライブラリのバージョンアップの影響もうける ◦ /icons だけは依存ライブラリの影響は少ない ◦ 他パッケージは
peer dependenciesが多い ▪ /react /tailwind-config /styled … 動作環境、依存ライブラリはどんどん変わる
今後の話 • /icons は a11y やパフォーマンスの課題を抱えている • Charcoalは品質をあげるステップに入った ◦ より安定、よりハイパフォーマンスであるべき
• Charcoalのぜんぶで頑張っている最中 • キリがないのであとでとっ捕まえて聞いてください デザイナーやiOSエンジニアも捕えておきます
宣伝 • Charcoalのセッションは他にもあります! ◦ SUB STAGE: cilvia「BOOTHにおけるCharcoal実践活用術」 現場で実際に行われているテーマのカスタムなどの話が聞けそうです ◦ SUB
STAGE: ああうえ「Charcoalをモバイルアプリで使う」 CharcoalのiOS開発メンバーの発表です • 懇親会パートでmimoはDJをします