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

React.js, Draft.jsで作る リッチテキストエディタ開発入門

React.js, Draft.jsで作る リッチテキストエディタ開発入門

Meguro.es #4 @wantedlyでのトーク内容です

mottox2

June 21, 2016
Tweet

More Decks by mottox2

Other Decks in Programming

Transcript

  1. React.js, Draft.jsͰ࡞Δ
    ϦονςΩετΤσΟλ։ൃೖ໳
    Meguro.es #4 @Wantedly
    ஛ຊ ༤و (@mottox2)

    View Slide

  2. γΰτͰίίϩΦυϧ
    ࣗݾ঺հ
    ஛ຊ ༤و @mottox2
    • Wantedly৽ଔҰ೥໨ͷΤϯδχΞ
    • ϑϩϯτΤϯυ͕޷͖
    • ʮϑΟʔυʯΛ࡞͍ͬͯ·͢

    View Slide

  3. දݱͷ෯Λ޿͛ΔͨΊʹ
    ϒϩάΤσΟλͷϦχϡʔΞϧΛߦͬͨ

    View Slide

  4. γΰτͰίίϩΦυϧ
    ϦονςΩετΤσΟλ։ൃ
    ϦονςΩετΤσΟλͷඞཁੑ
    ΤϯδχΞք۾ͰϚʔΫμ΢ϯʴϓϨϏϡʔ͕ྲྀߦ͍ͬͯΔɻ
    ී௨ͷਓ͔Βͨ͠ΒϦονςΩετΤσΟλ͕౰ͨΓલɻ
    ʮฤू͍ͯ͠Δݟͨ໨ʹެ։͞ΕΔ΋ͷʯͰ͋ͬͯཉ͍͠͸ͣɻ
    ϦονςΩετΤσΟλ։ൃͷਏ͞
    (=contenteditableͱͷઓ͍)
    ᶃ ϒϥ΢βʹΑͬͯڍಈ͕ҧ͏
    ᶄ ཤྺ؅ཧ͕େม
    ᶅ DOMΛ৮Δඞཁ͕͋Δ

    View Slide

  5. γΰτͰίίϩΦυϧ
    ͜Ε·Ͱ
    ҎલͷΤσΟλ
    React+Reduxߏ੒ͷதͰɺੜ
    ͷDOMΛ͍͍ͬͯͨ͡ɻ
    ֦ுͣ͠Β͍
    DOMΛ௚઀৮ͬͯ؅ཧ͍ͯ͠Δ෦෼

    View Slide

  6. γΰτͰίίϩΦυϧ
    Draft.jsͱ͸ʁ
    Facebookͷެ։͍ͯ͠ΔOSSɻ
    React.js্ͰϦονςΩετΤσΟλΛߏங͢ΔͨΊͷίϯϙʔωϯτΛఏڙ͠
    ͯ͘ΕΔɻ
    https://github.com/facebook/draft-js
    Ըܙ
    ᶃ ϒϥ΢βؒͷڍಈͷࠩΛٵऩͯ͘͠ΕΔɻ
    ᶄ ΤσΟλશମΛ1ͭͷStateͱͯ͠؅ཧ͢Δ͔Βɺཤྺ؅ཧ΋؆୯
    ᶅ DOM΋StateͰ͍࣋ͬͯΔͷͰɺJSΦϒδΣΫτͰ؅ཧͰ͖Δʢେ੾ʣ
    ߋʹɺReactίϯϙʔωϯτͰϦονͳදࣔ΋Ͱ͖Δɻ
    Draft.jsͷ࠾༻

    View Slide

  7. γΰτͰίίϩΦυϧ
    ී௨ͷinputλά
    class MyInput extends React.Component {
    constructor(props) {
    super(props);
    this.state = {value: ''};
    this.onChange = (e) => this.setState({value: e.target.value});
    }
    render() {
    return ;
    }
    }

    View Slide

  8. γΰτͰίίϩΦυϧ
    Draft.jsͰ؅ཧ͢Δ৔߹
    import React from ‘react’;
    import {Editor, EditorState} from 'draft-js';
    class MyEditor extends React.Component {
    constructor(props) {
    super(props);
    this.state = {editorState: EditorState.createEmpty()};
    this.onChange = (editorState) => this.setState({editorState});
    }
    render() {
    return onChange={this.onChange} />;
    }
    } EditorͷComponent
    Editorͷঢ়ଶΛද͢State
    input, textAreaͱಉ͡ײ֮Ͱ࢖͑Δ!͜ΕΛ֦ு͍ͯ͘͠

    View Slide

  9. γΰτͰίίϩΦυϧ
    Block
    Block
    [{
    depth: 0,
    entityRanges: [],
    inlineStyleRanges: [],
    key: "67fie",
    text: "ݟग़͠",
    type: "header-two"
    },{
    depth: 0,
    entityRanges: [],
    inlineStyleRanges: [],
    key: "67fie",
    text: "ී௨ͷςΩετ",
    type: "unstyled"
    }]
    ݟग़͠
    Preview
    ී௨ͷςΩετ
    typeΛม͑Δ͜ͱͰ
    ରԠ͢Δཁૉʹม͑Δ͜ͱ
    ͕Ͱ͖Δ
    (ex. h1..h6, blockquote, code)

    View Slide

  10. γΰτͰίίϩΦυϧ
    InlineStyle
    Block
    {
    depth: 0,
    entityRanges: [],
    inlineStyleRanges: [
    {
    length: 2
    offset: 0
    style: “BOLD”
    }
    ],
    key: "67fie",
    text: "ଠࣈʹͳΔ",
    type: "header-two"
    }
    InlineStyle
    ଠࣈʹͳΔ
    Preview
    StyleΛม͑Δ͜ͱͰ
    ରԠ͢ΔελΠϧΛ౰ͯΔ
    ͜ͱ͕Ͱ͖Δɻ
    (ex. BOLD, ITALIC, UNDERLINE)

    View Slide

  11. γΰτͰίίϩΦυϧ
    Entity
    Block
    {
    depth: 0,
    entityRanges: [
    {
    key: 0,
    length: 3,
    offset: 0
    }
    ],
    inlineStyleRanges: [],
    key: "67fie",
    text: "ϦϯΫʹͳΔ",
    type: "unstyled"
    }
    entityMap: {
    0: {
    data: {
    url: “http://wantedly.com“

    },
    mutability: “MUTABLE”,
    type: “LINK”,
    }

    }
    Entity
    Entity
    ϦϯΫʹͳΔ
    Preview
    จࣈɺ૷০Ҏ֎ͷ৘ใ͸
    EntityͰ؅ཧΛߦ͏ɻ

    View Slide

  12. γΰτͰίίϩΦυϧ
    DOM௚઀͞ΘΓͨ͘ͳ͍໰୊
    ղܾʂ
    ͍͍ײ͡ʹ৮Γ΍͍͢API͕ఏڙ͞Ε͍ͯΔͷͰ
    ޙ͸Block΍InlineStyle, EntityΛ͍͡Δ͚ͩͰྑ͍ɻ

    View Slide

  13. γΰτͰίίϩΦυϧ
    Custom Block Compoent
    ReactComponentΛ࢖ͬͨϦον
    ͳίϯϙʔωϯτ͕࡞ΕΔɻ
    Ԡ༻͢ΔͱɺEntityͷσʔλΛߋ
    ৽ͯ͠ΠϯλϥΫςΟϒͳײ͡ͷ
    ΋ͷΛ࡞ΕΔɻ
    data: {
    created_at : "2016-06-21T16:29:55.9
    id: 10
    provider_name: "Wantedly"
    thumbnail: “https://d2v9k5u4v94ulw
    title: "Ϟμϯͳ؀ڥͰReactΛॻ͖͍ͨ
    type: “link"
    updated_at: "2016-06-21T16:29:55.9
    url: "https://www.wantedly.com/pro
    },
    mutability: “IMMUTABLE",
    type: "EMBED"
    Preview
    Entity

    View Slide

  14. γΰτͰίίϩΦυϧ
    HTML΁ͷม׵
    • GithubʹDraft.jsͷσʔλܗ͔ࣜΒHTML΍ASTʹม׵͢
    ΔϥΠϒϥϦ͕ز͔ͭެ։͞Ε͍ͯΔɻ
    • WantedlyͰ͸RubyͰDraft.jsͷσʔλܗ͔ࣜΒHTMLʹ
    ม׵͢ΔίʔυΛॻ͍ͯରԠ͍ͯ͠Δɻ
    • iOS͕ωΠςΟϒΞϓϦͰهࣄΛදࣔ͢ΔํࣜΛ࠾༻ͯ͠
    ͓Γɺ΄΅Draft.jsͷσʔλܗࣜʹἧ͍͑ͯΔɻ

    View Slide

  15. γΰτͰίίϩΦυϧ
    Draft.jsͷਏ͍ͱ͜Ζ
    • ೔ຊʹ͋·Γ࢖͍ͬͯΔਓ͕͍ͳ͍ͷͰӳޠΛಡΉ͜ͱʹ
    ͳΔɻ
    • ࡉ͔͍ௐ੔Λ͢Δͱ͖ʹdraft.jsຊମͷίʔυಡΉඞཁ͕
    ͋Δɻ
    • ϚϧνόΠτจࣈݻ༗ͷਏ͍ڍಈ͕͋Δɻ
    • ݁ہΩϟϨοτͷൣғ؅ཧͷਏ͞͸࢒Δɻ
    • σϑΥϧτͷվߦͷڍಈ͕޷ΈͰͳͯ݁͘ߏ͍ͬͨ͡ɻ

    View Slide

  16. γΰτͰίίϩΦυϧ
    ಋೖͯ͠Έͨײ૝
    • Draft.jsΛಋೖ͢Δ͜ͱͰɺ։ൃָ͕ʹͳΔ
    ͭΒ͍ͱ͜Ζ͸͋Δ͚Ͳɺࠓ·ͰΑΓ͸͔ͳΓָɻ
    ։ൃָ͕ʹͳͬͨ෼ɺϢʔβʔ΋؆୯ʹهࣄΛ࡞ΕΔΑ͏
    ʹ͍͖͍ͯͨ͠ɻ

    View Slide

  17. γΰτͰίίϩΦυϧ
    ࠷ޙʹ

    View Slide

  18. Wantedly FeedͰ
    ΤϯδχΞϒϩάΛॻ͖·͠ΐ͏ʂ
    ࠾༻ʹܨ͕ΔʮWantedly͔ͩΒͦ͜ʯͷՁ஋Λఏڙ͠·͢

    View Slide