Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Spindle UIのつくりかた / Spindle UI: From Concept to Creation

Ameba Spindle
August 30, 2023

Spindle UIのつくりかた / Spindle UI: From Concept to Creation

Ameba Spindle

August 30, 2023
Tweet

More Decks by Ameba Spindle

Other Decks in Design

Transcript

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

    View Slide

  2. You can become a Spindler today

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  6. View Slide

  7. View Slide

  8. View Slide

  9. 01 Spindle UIとは?

    View Slide

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

    View Slide

  11. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  16. You are all set!

    View Slide

  17. View Slide

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

    View Slide

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

    View Slide

  20. やるよっ

    View Slide

  21. View Slide

  22. View Slide

  23. View Slide

  24. 03 Design Docを書く

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  28. スクリーンショット

    View Slide

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

    View Slide

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

    View Slide

  31. 使用例

    Top
    Team
    Amebaとは  


    View Slide

  32. を使わず、直接 要素も使用
    できます。各種フレームワークで定義された
    も同様に指定できます。その際には、現在地となるa
    要素にaria-current属性を付与してください。

    Top
    Amebaとは

    View Slide

  33. アクセシビリティ

    View Slide

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

    View Slide

  35. ● 現在位置を確認できる[SHOULD]
    ○ 現在位置は aria-current="page" を付与している
    ● HTMLの要素や属性を正しい役割で使用する[MUST]
    ○ パンくずリストのnav要素に aria-label="パンくずリス
    ト"、現在位置には aria-current="page" を付与してい

    ○ スクリーンリーダーでも機能落ちがなく、読み上げが過
    不足なく行われている

    View Slide

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

    View Slide

  37. 04 開発する

    View Slide

  38. yarn generate
    Powered by
    ジェネレート

    View Slide

  39. cd packages/spindle-ui
    yarn generate

    View Slide

  40. 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

    View Slide

  41. 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

    View Slide

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

    );
    };

    View Slide

  43. /* 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 (
    aria-label="パンくずリスト"
    className={`${BLOCK_NAME} ${BLOCK_NAME}--${variant}`}}
    >{...}
    );
    };

    View Slide

  44. /* 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 (
    aria-label="パンくずリスト"
    className={`${BLOCK_NAME} ${BLOCK_NAME}--${variant}`}}
    >{...}
    );
    };

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  48. # Breadcrumb

    ## Variant
    ### Standard



    Amebaとは



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

    View Slide

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

    View Slide

  50. 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(
    'パンくずリスト',
    );
    });
    });
    できるだけ
    自動的に
    テストします

    View Slide

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

    View Slide

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

    View Slide

  53. 05 公開する

    View Slide

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

    View Slide

  55. One more thing

    View Slide

  56. View Slide

  57. Congratulations, you are a Spindler!

    View Slide

  58. 06 FAQ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  63. @AmebaSpindle

    View Slide

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

    View Slide