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
Spindle UIのつくりかた / Spindle UI: From Concept to ...
Search
Ameba Spindle
August 30, 2023
Design
9.5k
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Spindle UIのつくりかた / Spindle UI: From Concept to Creation
Ameba Spindle
August 30, 2023
More Decks by Ameba Spindle
See All by Ameba Spindle
Spindle 2025: How AI Agents and Design Systems Are Transforming Web Development
spindle
0
140
MCPで変わる Amebaデザインシステム「Spindle」の開発
spindle
2
4.5k
デザインシステムの力 Webデザイナーとエンジニアのための実践ガイド / The Power of Design System
spindle
10
12k
Ameba Illustration Guidelines
spindle
2
890
Amebaデザインシステム Spindleの開発 / The Development of Spindle
spindle
6
3.4k
Amebaブログ Brand Guidelines
spindle
5
44k
Other Decks in Design
See All in Design
デザインハーネス 〜AIが生成する"デザイン"の妥当性を、誰がどう担保するのか〜 / PdEConf2026 Design Harness
kgsi
12
20k
「惜しいデザイン」 を生み出さないための AIレビューループ
0b1tk
3
4.4k
「おすすめ」はなぜ信用されないのか - 信頼を築くUI/UX設計
ryu1013
0
260
デザインツールを開く前に その画面は誰に何と言わせたい?受託UIデザイナーが顧客解像度を高める 「打ち合わせの場での確かめ方」
garyuten
1
220
再設計される業務 - AIにより再設計される "デザインワークフロー" / AI Ops Lab #2 Redesigned orkflows
kgsi
0
910
デザインワークフローの最前線。 ログラスでのAI活用の現在地
ukaoli
1
3k
PAMPHLET.pdf
mhand01
0
1.8k
デザインとフロントエンドの境界が融ける Claude Code × Figma
littlebusters
2
3.5k
Rethinking IFUs: What Board Game Rulebooks Contribute to IFU Usability
deadlinepoet
0
370
Debiasing Your Software Design Decision-Making @ Flowcon '26
baasie
1
180
(2026 FlowCon Keynote) Sociotechnical Architecture Finding Flow
xinyao
0
120
【CEDEC2026】派手さと見やすさは両立できる!『Shadowverse: Worlds Beyond』エフェクト・3D背景の超進化したビジュアル設計
cygames
PRO
1
1.9k
Featured
See All Featured
Rails Girls Zürich Keynote
gr2m
96
14k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2.2k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
490
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
230
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
420
Accessibility Awareness
sabderemane
1
210
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
300
Facilitating Awesome Meetings
lara
57
7.1k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
570
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
500
Transcript
Spindle UIのつくりかた 原 一成 2023年8月30日 Encraft #6
You can become a Spindler today
コンポーネントをつくる前に Spindle UIとは? 要件定義とスタイリング Design Docを書く 00 01 02 03
CONTENTS 実装する 04 公開する 05 FAQ 06
00 コンポーネントをつくる前に
デザインシステムSpindle(スピンドル)は ”Amebaらしさ”を一貫して届けるための 仕組みです。
None
None
None
01 Spindle UIとは?
Spindle UIはSpindleに内包されたUIライ ブラリの総称です。 Amebaらしさを一貫して表現するための 必要十分なComponent郡で、その全てが Amebaのブランド指針に準拠します。
None
Spindle UIの Design Doc 見てみましょう
目指すこと 各Webアプリケーションで再作成する必 要のない小さな単位のコンポーネントを 作成し、ライブラリとして配信すること を目指します。
目指さないこと このコンポーネントだけでWebアプリ ケーションを作れるような、大きなライ ブラリを提供することを目指していませ ん。
概要 Amebaの開発での利用実績を踏まえ、以下の点を考慮してライブラ リを提供します。 • Reactコンポーネントの提供: Amebaで最も利用されているUIライブラリの Reactで作られたミニマムなコンポーネントを提供します • スタイルが定義されたCSSの提供: UIライブラリを使用しないLPなどのプ
ロジェクトにCSSで表現できる範囲の振る舞いを提供します • UIコンポーネントカタログ中心の開発: 作られたコンポーネントはすぐ にテストされ、表示を確認します • 管理されたファイルサイズ: 共通処理が集まるため、大きくなりがちなUIラ イブラリのファイルサイズが規定を超さないようにします
You are all set!
None
エラー コンポーネント 欲しいっ! Modal つ〜くろ
02 要件定義とスタイリング
やるよっ
None
None
None
03 Design Docを書く
Design Docにはコードだけでは 読み取れないコンポーネントが 作られた背景や設計のポイント を記載します。 また、レビューを通じて不明点 や考慮できていない箇所を洗い 出す役割も兼ねています。 仕様書ではないので完璧に記述 する必要はありません!
はみ出した時 は折り返す? スクロール? Variant つくりま しょう
概要・背景 パンくずリストは、Webサイトのページ階層をリス ト化して表示し、現在地を示すコンポーネントで す。Webサイトを訪れたユーザーが、サイト内のど このページを閲覧しているのか把握するために配置 します。現在地を把握することでWebサイトの構造 を理解しやすくなるため、アクセシビリティやSEO の観点でも効果的です。
スクリーンショット
デザイントークン • Surface Secondary (背景色) • Text Accent Primary (リンク色)
• Text Low Emphasis (現在地テキスト色) • Object Low Emphasis (矢印の色) • Focus Clarity (フォーカスリングの色)
プロパティ type Props { children?: React.ReactNode; variant?: 'standard' | 'emphasized';
wrap?: 'wrap'; // 画面幅に入り切らなくなったタイミングで折り返して表示します }
使用例 <BreadcrumbList> <BreadcrumbItem href="/top">Top</BreadcrumbItem> <BreadcrumbItem href="/team">Team</BreadcrumbItem> <BreadcrumbItem href="/about" current>Amebaとは </BreadcrumbItem>
</BreadcrumbList>
<BreadcrumbItem> を使わず、直接 <a> 要素も使用 できます。各種フレームワークで定義された <Link> も同様に指定できます。その際には、現在地となるa 要素にaria-current属性を付与してください。 <BreadcrumbList> <Link
href="/top">Top</Link> <a aria-current="page">Amebaとは</a> </BreadcrumbList>
アクセシビリティ
• テキストサイズを拡大縮小できる[MUST] ◦ 画面を200%拡大・文字サイズを2倍に変更して も、情報が欠落しない ▪ Wrapオプション指定時は、適切に文字が折り 返される ▪ その他は、横スクロールで全てのテキストを
表示できる
• 現在位置を確認できる[SHOULD] ◦ 現在位置は aria-current="page" を付与している • HTMLの要素や属性を正しい役割で使用する[MUST] ◦ パンくずリストのnav要素に
aria-label="パンくずリス ト"、現在位置には aria-current="page" を付与してい る ◦ スクリーンリーダーでも機能落ちがなく、読み上げが過 不足なく行われている
Spindle 使っていれば アクセシブル
04 開発する
yarn generate Powered by ジェネレート
cd packages/spindle-ui yarn generate
cd packages/spindle-ui yarn generate ? Please select a document. (Use
arrow keys) ❯ component ? Please select the output destination directory. (Use arrow keys or type to search) ❯ src/ ? Please enter a component name. Breadcrumb
cd packages/spindle-ui yarn generate ? Please select a document. (Use
arrow keys) ❯ component ? Please select the output destination directory. (Use arrow keys or type to search) ❯ src/ ? Please enter a component name. Breadcrumb 🐶 Generated 7 files! ✔ src/Breadcrumb/index.ts ✔ src/Breadcrumb/Breadcrumb.tsx ✔ src/Breadcrumb/Breadcrumb.css ✔ src/Breadcrumb/Breadcrumb.stories.mdx ✔ src/Breadcrumb/Breadcrumb.test.mdx ✔ src/index.ts ✔ src/index.css
/* src/Breadcrumb/Breadcrumb.tsx */ import React from 'react'; type Props =
{}; const BLOCK_NAME = 'spui-Breadcrumb'; export const Breadcrumb: React.FC<Props> = ({}) => { return ( <div className={BLOCK_NAME}></div> ); };
/* src/Breadcrumb/Breadcrumb.tsx */ import React from 'react'; type Props =
{ variant: 'standard' | 'emphasized' }; const BLOCK_NAME = 'spui-Breadcrumb'; export const Breadcrumb: React.FC<Props> = ({ variant = 'standard' }) => { return ( <nav aria-label="パンくずリスト" className={`${BLOCK_NAME} ${BLOCK_NAME}--${variant}`}} >{...}</nav> ); };
/* src/Breadcrumb/Breadcrumb.tsx */ import React from 'react'; type Props =
{ variant: 'standard' | 'emphasized' }; const BLOCK_NAME = 'spui-Breadcrumb'; export const Breadcrumb: React.FC<Props> = ({ variant = 'standard' }) => { return ( <nav aria-label="パンくずリスト" className={`${BLOCK_NAME} ${BLOCK_NAME}--${variant}`}} >{...}</nav> ); };
/* src/Breadcrumb/Breadcrumb.css */ .spui-Breadcrumb { }
/* src/Breadcrumb/Breadcrumb.css */ .spui-Breadcrumb { overflow: auto hidden; } .spui-Breadcrumb--wrap
{ overflow: hidden; } … .spui-Breadcrumb--emphasized { background-color: var(--color-surface-secondary); } … .spui-Breadcrumb a:not([aria-current]) { color: var(--color-text-accent-primary); font-weight: bold; } .spui-Breadcrumb a[aria-current] { color: var(--color-text-low-emphasis); font-weight: normal; } デザイントークンは spindle-tokens.css で定義されています
/* src/Button/Button.css */ :root { --Button--contained-backgroundColor: var(--color-surface-accent-primary); --Button--contained-color: var(--color-text-high-emphasis-inverse); --Button--contained-onActive-backgroundColor:
var(--primary-green-100); --Button--contained-onHover-backgroundColor: var(--primary-green-100); }
# Breadcrumb <Meta title="Breadcrumb" component={Breadcrumb} /> ## Variant ### Standard
<Preview withSource="open"> <Story name="Standard"> <BreadcrumbList variant="standard"> <BreadcrumbItem href="#" current>Amebaとは</BreadcrumbItem> </Button> </Story> </Preview> Standard Variantはタップエリアを確保する目的でテキストに余白が指定されています。ページ内での左端 を揃えたい場合には、個別に余白を指定しBreadcrumb要素の位置を調整してください。 Storyは Docs, VRT用途 でも使います
見た目に関わる 色や形、レイアウト をテストします
import React from 'react'; import { render, screen } from
'@testing-library/react'; import { BreadcrumbList, BreadcrumbItem } from './Breadcrumb; describe('<Breadcrumb />', () => { test('having aria attributes', async () => { render( <BreadcrumbList> <BreadcrumbItem href="/about" current>Amebaとは</BreadcrumbItem> </BreadcrumbList> ); expect(screen.getByRole('navigation').getAttribute('aria-label')).toEqual( 'パンくずリスト', ); }); }); できるだけ 自動的に テストします
もし作り途中に気になることが出てきたら、設計フェーズに戻り確認します 設計 実装 ですね 変えましょう! もしかして... 実現できない!?
git commit -m “feat(spindle-ui): create Breadcrumb component”
05 公開する
git switch -c release/minor git push origin release/minor CONTRIBUTING.md
One more thing
None
Congratulations, you are a Spindler!
06 FAQ
Q: 取り組みでよかったことは? ブランドを一貫して届けるための仕組み にしたことで、職種を超えたコラボレー ションが生まれ続けました。
Q: Spindle UIでこだわったことは? • 単体で機能するコンポーネント集 • プロダクトで使われるための構成 • Web標準的なアプローチ
Q: Spindleはなぜ公開しているのですか • ブランディングを目的にしているから • 誰でもアクセスしやすいから • 品質をあげたいから • 採用目的...
Q: 帽子...アレ(Spindle)ですか? ふふふ、Suzuri です (suzuri.jp/ameba-spindle)
@AmebaSpindle
株式会社サイバーエージェント Tech Lead / Web Developer 原 一成 Hara Kazunari
@herablog @herablog お疲れ様 でした