🎃

FramerのCodeComponent内でスタイリングする

2022/08/19に公開

動機

FramerSitesでサイトを作成した際に、長い文章のみのページが有りMarkdownで対応したいと思いました。
Markdownについてはmarked.jsを使うことで実現出来ました。ただ、そのままだと読み辛いのでスタイリングを調整したいと思い、調べた結果になります。
また、今回の件でFrameのCodeComponentが、かなり自由にコーディング出来ることに今後の可能性を感じました。

CodeComponent

CodeComponentについてはこちら

Markdown形式のテキストを受け取り、DOMエレメントとしてレンダリングするCodeComponentのコード全体です。(意図が分かる程度に調整しています)

MarkdownComponent.tsx
import { marked } from "https://jspm.dev/marked@4.0.18"
import styled from "styled-components"

import { addPropertyControls, ControlType } from "framer"

const renderer = {
    table(header, body) {
        return `<div data-type="table-wrapper">
            <table>
            ${header}${body}
            </table>
        </div>`
    },
}
marked.use({ renderer })

const MarkdownStyle = styled("div")`
    background-color: #fff;
    div[data-type="table-wrapper"] {
        margin: 0.8em 0;
    }
    @media screen and (max-width: 480px) {
        div[data-type="table-wrapper"] {
          margin: 0;
        }
    }
`

const defaultMarkdown = `
# Heading -1
## Heading - 2
### Heading - 3
#### Heading - 4
##### Heading - 5
###### Heading - 6
`

export default function MarkdownView(props) {
    return (
        <MarkdownStyle
            dangerouslySetInnerHTML={{ __html: marked.parse(props.markdown) }}
        />
    )
}

addPropertyControls(MarkdownView, {
    markdown: {
        type: ControlType.String,
        defaultValue: defaultMarkdown,
        displayTextArea: true,
    },
})

読み込み

marked.jsstyled-componentsを読み込みます。
styled-componentsはFramerにビルトインされているようです。markedはjspm.devを使って読み込んでいます。
framerからはCodeComponentで値を受け取るためのメソッドを読み込みます。

import { marked } from "https://jspm.dev/marked@4.0.18"

import styled from "styled-components"
import { addPropertyControls, ControlType } from "framer"

スタイリングする

styled-componentsを使って通常通りスタイリングするだけです。
@mediaも使えるので、少し手間ですがビジュアルエディタとブレークポイントを揃えれば意図したデザインを適用出来ます。

const MarkdownStyle = styled("div")`
    background-color: #fff;
    div[data-type="table-wrapper"] {
        margin: 0.8em 0;
    }
    @media screen and (max-width: 480px) {
        div[data-type="table-wrapper"] {
          margin: 0;
        }
    }
`

スタイルを適用する

スタイルを当てるのもReactの通常通りです。
propsのmarkdownにはビジュアルエディタからMarkdown形式のテキストが送られてきます。

export default function MarkdownView(props) {
    return (
        <MarkdownStyle
            dangerouslySetInnerHTML={{ __html: marked.parse(props.markdown) }}
        />
    )
}

感想

キレイなコードかは分かりませんが、これでReactのコードコンポーネントがFramer上で使えるのはとても便利でした。
CodeComponentの少し使い辛い点として、プレビュー画面でコード(DOM)が確認出来ないのが不満点です。特に今回のようにコードでスタイリングしようとすると、プレビューでエレメントの名前や構造を確認したいのですが、簡単には行きません。公開前、あるいは開発用のプロジェクトでパブリッシュしてしまうのが一番早いかも知れません。
(スタイリングした結果はプレビュー画面で反映されます)

バグ?

今回プレビューでは問題ないレイアウトだったのが、パブリッシュするとプレビューと違うというシーンに遭遇しました。
多分プレビューでFramerが指定しているCSS(UI用?)が当たってしまっているのかもしれません。なので、パブリッシュ後をちゃんと確認はした方が良さそうです。

まだ、発展途上なところは多いですが、足りないコンポーネントが機能付きで作れるのはFramerの魅力だと思います。

Discussion