🦄

Framer + RemixでWebサイトをつくる #13 - Codeで表現する - Code Componentの基本編

2021/12/26に公開約11,500字

引き続き開催しているもくもく会「Kamakura MokMok Hack」のサイトをFramer + Remixでつくっていきます。サイトの要件などに興味ある方は1日目の記事をご覧ください。

次のものはここまでFramerでつくったもののプレビューです。

https://framer.com/share/kamakura-dev-code-overrides--vnC8UVzkLoMK0t9yiXJa/Ih6d4c8rJ

13日目 - Codeでいろいろ表現する

えっと、これを書いているのは12月26日です。アドベントカレンダーとは一体…という感じだし、全然Remixの話がでてきませんが。。 とりあえずやれるだけのことはやろうという今はそういう気持ちです。

というわけで、前回はCode Overridesの話でやっとFigmaになくてFramerあるものの話ができました。今回はComponent丸ごとコードで作れる「Code Components」の話です。

と言いたいけど、今のところこの記事のテーマの要件的に別にCode Componentが必要な箇所がないので、未着手のイベントページでやってみます。

ただ、その前にCode Componentsの作り方をまとめます。

Code Componentsの作り方

Code Componentsを作成するには、Framerの左カラムにある「Assets」セクションを開いて、そのセクションタイトルの右側にある「Components」をクリックして「Code」に切り替えます。

切り替えると下部に「Create Code File」ボタンが表示されるのでそれをクリックでエディタが起動します。

デフォルトはサンプルコードが記入してあります。

import { addPropertyControls, ControlType } from "framer"
import { motion } from "framer-motion"

// Learn more: https://www.framer.com/docs/guides/code-components/

export default function Event(props) {
    const { text, onTap, style } = props

    // "...style" enables switching between auto & fixed sizing
    // Learn more: https://www.framer.com/docs/guides/auto-sizing
    return (
        <motion.div style={{ ...style, ...containerStyle }}>
            <motion.div
                style={squareStyle}
                onTap={onTap}
                whileTap={{
                    scale: 1.25,
                    rotate: 90,
                    backgroundColor: "#07F",
                }}
            >
                {text}
            </motion.div>
        </motion.div>
    )
}

Event.defaultProps = {
    text: "Tap",
}

// Learn More: https://www.framer.com/docs/property-controls/
addPropertyControls(Event, {
    text: {
        title: "Text",
        type: ControlType.String,
    },
    onTap: {
        type: ControlType.EventHandler,
    },
})

const containerStyle = {
    display: "flex",
    justifyContent: "center",
    alignItems: "center",
    overflow: "hidden",
}

const squareStyle = {
    margin: 50,
    padding: 50,
    color: "white",
    fontWeight: 600,
    borderRadius: 25,
    backgroundColor: "#09F",
    width: "max-content",
    whiteSpace: "pre-wrap" as const,
    flexShrink: 0,
}

ほぼ普通のReact Componentですが、FramerのCode Componentsとしては以下が違うところです。

addPropertyControls(Event, {
    text: {
        title: "Text",
        type: ControlType.String,
    },
    onTap: {
        type: ControlType.EventHandler,
    },
})

このaddPropertyControls()にReact Componentを渡して、任意のプロパティについて定義することでFramerのコンパネにこれらが表示され値を入力できるようになります。

各ControlTypeには次のプロパティが用意されています。ControlTypeによっては使えないものもあります。

Property 説明 関連ControlType
title string コンパネに表示するラベルのこと 全て
type ControlType ControlTypeを指定する。種類は次のものがあります。 String, Number, Transition, Image, FusedNumber, File, Enum, ComponentInstance, Color, Boolean, Object, Array 全て
description string 項目の説明を記載できます 全て
defaultValue string デフォルト値を設定できます 全て
placeholder string 入力欄に案内のテキストを設定できます String
displayTextArea boolean テキストエリア(複数行の入力)を許可するかどうか String
enabledTitle string スイッチでtrueの際のラベル Boolean
disabledTitle string スイッチでfalseの際のラベル Boolean
options string[] セレクトリストの値の集合。配列でいうところのKeyと同じ。 ["apple", "banana", "orange"] Enum
optionTitles string[] セレクトリストの値の集合。配列でいところのValueと同じ。 ["りんご", "ばなな", "オレンジ"] Enum
toggleKey `string number map`
toggleTitles [string, string] 全てか4つ入力するかの切り替えボタンのラベル(マウスカーソル乗せると表示されます) 配列に文字列を2つのみ指定できます。 例) ["All","Indivial"] FusedNumber
valueKeys [string, string, string, string] FusedNumberで各値のkey名 FusedNumber
valueLabels [string, string, string, string] FusedNumberの各値のラベル FusedNumber
min number 最小値を設定できます Number, FusedNumber
max number 最大値を設定できます Number
unit string 数値の単位を設定できます。unit: 円にして100と入力すると100円と表示されます Number
step number 数値のスライドで増分。step:2にしてスライドを動かすと2づつ加算・減算します Number
displayStepper boolean trueにすると数値スライドを[-][+]のステッパーボタンに変更できます Number
allowedFileTypes string[] 許可するファイルの拡張子を指定します。例)["mov", "mp4", "mp3] File

ControlType

ControlTypeは次の種類があります。

文字列 ControlType.String

addPropertyControls(Component, {
    fruits: {
        title: "フルーツ",
        type: ControlType.Enum,
        defaultValue: "banana",
        options: ["apple", "banana", "orange"],
        optionTitles: ["りんご", "バナナ", "オレンジ"],
    },
})


数列 ControlType.Number

addPropertyControls(Component, {
    person: {
        title: "人数",
        type: ControlType.Number,
        defaultValue: 1,
        description: "ControlType.Number",
        min: 1,
        max: 10,
        unit: "人",
        step: 2,
        displayStepper: true,
    },
})


複数の数列 ControlType.FusedNumber

4つの異なる数値入力フィールドとそれらの数値をまとめて指定できるフィールドのセット。

addPropertyControls(Component, {
    padding: {
        title: "Padding",
        type: ControlType.FusedNumber,
        defaultValue: 2,
        description: "ControlType.Number",
        min: 1,
        toggleKey: "isMixed",
        toggleTitles: ["すべて", "個別"],
        valueKeys: ["topLeft", "topRight", "bottomRight", "bottomLeft"],
        valueLabels: ["左上", "右上", "右下", "左下"],
    },
})


スイッチ ControType.Boolean

addPropertyControls(Component, {
    hasBorder: {
        title: "Border",
        type: ControlType.Boolean,
        defaultValue: true,
        description: "ControlType.Boolean",
        disabledTitle: "非表示",
        enabledTitle: "表示",
    },
})


色 ControlType.Color

Framer Toolsを入れておけばローカル上のカラーも拾えます。※Windowsは準備中らしいです。
Framer Toolsのダウンロードは以下からできます。

https://www.framer.com/support/using-framer/framer-tools/
addPropertyControls(Component, {
    background: {
        title: "背景色",
        type: ControlType.Color,
        defaultValue: "#4DC6FF",
        description: "ControlType.Color",
    },
})


セレクトリスト ControlType.Enum

addPropertyControls(Component, {
    fruits: {
        title: "フルーツ",
        type: ControlType.Enum,
        defaultValue: "banana",
        options: ["apple", "banana", "orange"],
        optionTitles: ["りんご", "バナナ", "オレンジ"],
        description: "ControlType.Enum",
        displaySegmentedControl: false,
    },
})


画像 ControlType.Image

ファイル参照した際には画像のパスが

addPropertyControls(Component, {
    photo: {
        title: "写真",
        type: ControlType.Image,
        description: "ControlType.Image",
    },
})


ファイル ControlType.File

FramerではCode Componentsで動画や音楽プレイヤーを自作することもできますし、Insertの中に動画・音楽プレイヤーコンポーネントも用意されているのでそれ用にファイルを指定することができます。

addPropertyControls(Component, {
    movie: {
        title: "動画",
        type: ControlType.File,
        allowedFileTypes: ["mov", "mp4"],
        description: "ControlType.File",
    },
})


イベント(Interaction) ControlType.EventHandler

Interactionを指定すると、それをpropsでCode Componentに渡せる様になります。

addPropertyControls(Component, {
    onTap: {
        title: "TapHandle",
        type: ControlType.EventHandler,
        description: "ControlType.EventHandler",
    },
})


コンポーネント ControlType.ComponentInstance

Framer上でつくったSmart Componentsを渡せます。

addPropertyControls(Component, {
    animeComponente: {
        title: "Component",
        type: ControlType.ComponentInstance,
        description: "ControlType. ComponentInstance",
    },
    text: {
        title: "Text",
        type: ControlType.String,
        placeholder: "入力…",
        defaultValue: "デフォルト",
        description: "ControlType.String",
    },
})

// Component
export default function Component(props) {
    const { text, animeComponente, style } = props

    return (
        <motion.div style={{ ...style, ...containerStyle }}>
            <div style={{ textAlign: "center" }}>{text}</div>
            <div
                style={{
                    display: "flex",
                    justifyContent: "center",
                }}
            >
                <div
                    style={{
                        width: "200px",
                        height: "200px",
                        position: "relative",
                        overflow: "hidden",
                        borderRadius: 999,
                    }}
                >
                    {animeComponente}
                </div>
            </div>
        </motion.div>
    )
}

ComponentInstanceのプレビュー

LottieアニメーションComponentを子Componentとして受け取って表示

https://framer.com/share/kamakura-dev-code-components-component-instance--c6fLvShw4gLUHA8tgT7S/yolKfqhLV

オブジェクト ControlType.Object

controls で複数のプロパティを一つのオブジェクトとしてまとめられます。

addPropertyControls(Component, {
    user: {
        title: "ユーザ",
        type: ControlType.Object,
        controls: {
            name: { type: ControlType.String, title: "ユーザ名" },
            photo: { type: ControlType.Image, title: "写真" },
        },
        description: "ControlType.Object",
    },
})


配列 ControlType.Array

配列も扱えます。一覧系のComponentを作りたい時に役に立ちます。

addPropertyControls(Component, {
    friends: {
        title: "フレンド",
        type: ControlType.Array,
        control: {
	    tite: "ユーザ",
            type: ControlType.Object,
            controls: {
                name: { type: ControlType.String, title: "ユーザ名" },
                photo: { type: ControlType.Image, title: "写真" },
            },
        },
        description: "ControlType.Array",
    },
})

「➕」ボタンをクリックすると配列の要素が追加されます。並び替えもできます。 option + クリックで削除もできます。



今回はCode Componentsの基本について書きました。次回はこのCode Componentsnpm packageについて説明し、その後にCode Componentsを使ってイベント一覧をconnpass APIから取得して表示するコンポーネントを作成します。もうアドベントカレンダー終わってるけど。


Discussion

ログインするとコメントできます