Slide 1

Slide 1 text

Spindle UIのつくりかた 原 一成 2023年8月30日 Encraft #6

Slide 2

Slide 2 text

You can become a Spindler today

Slide 3

Slide 3 text

コンポーネントをつくる前に Spindle UIとは? 要件定義とスタイリング Design Docを書く 00 01 02 03 CONTENTS 実装する 04 公開する 05 FAQ 06

Slide 4

Slide 4 text

00 コンポーネントをつくる前に

Slide 5

Slide 5 text

デザインシステムSpindle(スピンドル)は ”Amebaらしさ”を一貫して届けるための 仕組みです。

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

01 Spindle UIとは?

Slide 10

Slide 10 text

Spindle UIはSpindleに内包されたUIライ ブラリの総称です。 Amebaらしさを一貫して表現するための 必要十分なComponent郡で、その全てが Amebaのブランド指針に準拠します。

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

Spindle UIの Design Doc 見てみましょう

Slide 13

Slide 13 text

目指すこと 各Webアプリケーションで再作成する必 要のない小さな単位のコンポーネントを 作成し、ライブラリとして配信すること を目指します。

Slide 14

Slide 14 text

目指さないこと このコンポーネントだけでWebアプリ ケーションを作れるような、大きなライ ブラリを提供することを目指していませ ん。

Slide 15

Slide 15 text

概要 Amebaの開発での利用実績を踏まえ、以下の点を考慮してライブラ リを提供します。 ● Reactコンポーネントの提供: Amebaで最も利用されているUIライブラリの Reactで作られたミニマムなコンポーネントを提供します ● スタイルが定義されたCSSの提供: UIライブラリを使用しないLPなどのプ ロジェクトにCSSで表現できる範囲の振る舞いを提供します ● UIコンポーネントカタログ中心の開発: 作られたコンポーネントはすぐ にテストされ、表示を確認します ● 管理されたファイルサイズ: 共通処理が集まるため、大きくなりがちなUIラ イブラリのファイルサイズが規定を超さないようにします

Slide 16

Slide 16 text

You are all set!

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

エラー コンポーネント 欲しいっ! Modal つ〜くろ

Slide 19

Slide 19 text

02 要件定義とスタイリング

Slide 20

Slide 20 text

やるよっ

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

03 Design Docを書く

Slide 25

Slide 25 text

Design Docにはコードだけでは 読み取れないコンポーネントが 作られた背景や設計のポイント を記載します。 また、レビューを通じて不明点 や考慮できていない箇所を洗い 出す役割も兼ねています。 仕様書ではないので完璧に記述 する必要はありません!

Slide 26

Slide 26 text

はみ出した時 は折り返す? スクロール? Variant つくりま しょう

Slide 27

Slide 27 text

概要・背景 パンくずリストは、Webサイトのページ階層をリス ト化して表示し、現在地を示すコンポーネントで す。Webサイトを訪れたユーザーが、サイト内のど このページを閲覧しているのか把握するために配置 します。現在地を把握することでWebサイトの構造 を理解しやすくなるため、アクセシビリティやSEO の観点でも効果的です。

Slide 28

Slide 28 text

スクリーンショット

Slide 29

Slide 29 text

デザイントークン ● Surface Secondary (背景色) ● Text Accent Primary (リンク色) ● Text Low Emphasis (現在地テキスト色) ● Object Low Emphasis (矢印の色) ● Focus Clarity (フォーカスリングの色)

Slide 30

Slide 30 text

プロパティ type Props { children?: React.ReactNode; variant?: 'standard' | 'emphasized'; wrap?: 'wrap'; // 画面幅に入り切らなくなったタイミングで折り返して表示します }

Slide 31

Slide 31 text

使用例 Top Team Amebaとは  

Slide 33

Slide 33 text

アクセシビリティ

Slide 34

Slide 34 text

● テキストサイズを拡大縮小できる[MUST] ○ 画面を200%拡大・文字サイズを2倍に変更して も、情報が欠落しない ■ Wrapオプション指定時は、適切に文字が折り 返される ■ その他は、横スクロールで全てのテキストを 表示できる

Slide 35

Slide 35 text

● 現在位置を確認できる[SHOULD] ○ 現在位置は aria-current="page" を付与している ● HTMLの要素や属性を正しい役割で使用する[MUST] ○ パンくずリストのnav要素に aria-label="パンくずリス ト"、現在位置には aria-current="page" を付与してい る ○ スクリーンリーダーでも機能落ちがなく、読み上げが過 不足なく行われている

Slide 36

Slide 36 text

Spindle 使っていれば アクセシブル

Slide 37

Slide 37 text

04 開発する

Slide 38

Slide 38 text

yarn generate Powered by ジェネレート

Slide 39

Slide 39 text

cd packages/spindle-ui yarn generate

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

/* src/Breadcrumb/Breadcrumb.tsx */ import React from 'react'; type Props = {}; const BLOCK_NAME = 'spui-Breadcrumb'; export const Breadcrumb: React.FC = ({}) => { return (
); };

Slide 43

Slide 43 text

/* src/Breadcrumb/Breadcrumb.tsx */ import React from 'react'; type Props = { variant: 'standard' | 'emphasized' }; const BLOCK_NAME = 'spui-Breadcrumb'; export const Breadcrumb: React.FC = ({ variant = 'standard' }) => { return ( {...} ); };

Slide 44

Slide 44 text

/* src/Breadcrumb/Breadcrumb.tsx */ import React from 'react'; type Props = { variant: 'standard' | 'emphasized' }; const BLOCK_NAME = 'spui-Breadcrumb'; export const Breadcrumb: React.FC = ({ variant = 'standard' }) => { return ( {...} ); };

Slide 45

Slide 45 text

/* src/Breadcrumb/Breadcrumb.css */ .spui-Breadcrumb { }

Slide 46

Slide 46 text

/* 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 で定義されています

Slide 47

Slide 47 text

/* 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); }

Slide 48

Slide 48 text

# Breadcrumb ## Variant ### Standard Amebaとは Standard Variantはタップエリアを確保する目的でテキストに余白が指定されています。ページ内での左端 を揃えたい場合には、個別に余白を指定しBreadcrumb要素の位置を調整してください。 Storyは Docs, VRT用途 でも使います

Slide 49

Slide 49 text

見た目に関わる 色や形、レイアウト をテストします

Slide 50

Slide 50 text

import React from 'react'; import { render, screen } from '@testing-library/react'; import { BreadcrumbList, BreadcrumbItem } from './Breadcrumb; describe('', () => { test('having aria attributes', async () => { render( Amebaとは ); expect(screen.getByRole('navigation').getAttribute('aria-label')).toEqual( 'パンくずリスト', ); }); }); できるだけ 自動的に テストします

Slide 51

Slide 51 text

もし作り途中に気になることが出てきたら、設計フェーズに戻り確認します 設計 実装 ですね 変えましょう! もしかして... 実現できない!?

Slide 52

Slide 52 text

git commit -m “feat(spindle-ui): create Breadcrumb component”

Slide 53

Slide 53 text

05 公開する

Slide 54

Slide 54 text

git switch -c release/minor git push origin release/minor CONTRIBUTING.md

Slide 55

Slide 55 text

One more thing

Slide 56

Slide 56 text

No content

Slide 57

Slide 57 text

Congratulations, you are a Spindler!

Slide 58

Slide 58 text

06 FAQ

Slide 59

Slide 59 text

Q: 取り組みでよかったことは? ブランドを一貫して届けるための仕組み にしたことで、職種を超えたコラボレー ションが生まれ続けました。

Slide 60

Slide 60 text

Q: Spindle UIでこだわったことは? ● 単体で機能するコンポーネント集 ● プロダクトで使われるための構成 ● Web標準的なアプローチ

Slide 61

Slide 61 text

Q: Spindleはなぜ公開しているのですか ● ブランディングを目的にしているから ● 誰でもアクセスしやすいから ● 品質をあげたいから ● 採用目的...

Slide 62

Slide 62 text

Q: 帽子...アレ(Spindle)ですか? ふふふ、Suzuri です (suzuri.jp/ameba-spindle)

Slide 63

Slide 63 text

@AmebaSpindle

Slide 64

Slide 64 text

株式会社サイバーエージェント Tech Lead / Web Developer 原 一成 Hara Kazunari @herablog @herablog お疲れ様 でした