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

[LT] Type First な Form 開発のご紹介

hedrall
October 31, 2024
65

[LT] Type First な Form 開発のご紹介

hedrall

October 31, 2024
Tweet

Transcript

  1. 2 自己紹介
 2016-2021 朝日新聞社
 
 2021-2024 カケハシ
 
 2024- RightTouch

    (PLAIDグループ)
 
 
 
 現職: 新規プロダクトの立ち上げリード 
 
 好きな技術: TS, React, AWS, DDD
 
 趣味: 家庭菜園・園芸・多肉植物栽培 
 
 
 
 Hedrall
 X: @_hedrall

  2. 5 そこで...
 • ⭐14.3k
 
 • JSON Schema で Form

    を定義できる
 
 
 react-jsonschema-form
 https://rjsf-team.github.io/react-jsonschema-form/
  3. モデル定義 
 8 /** * @title Eメールアドレス */ type Email

    = { type: 'email '; address: string }; /** * @title お電話番号 */ type Phone = { type: 'phone'; number: string }; export interface お問い合わせForm { 氏名: string; お問い合わせの種類: 'ご質問' | 'ご要望' | 'その他'; お問い合わせ内容: string; 日中の連絡先: Email | Phone; 備考?: string; }
  4. モデル定義 
 9 /** * @title Eメールアドレス */ type Email

    = { type: 'email '; address: string }; /** * @title お電話番号 */ type Phone = { type: 'phone'; number: string }; export interface お問い合わせForm { 氏名: string; お問い合わせの種類: 'ご質問' | 'ご要望' | 'その他'; お問い合わせ内容: string; 日中の連絡先: Email | Phone; 備考?: string; } ENUM
 ANY OF
 OPTIONAL

  5. typescript-json-schema を実行 !
 1 0 npx typescript-json-schema \ --titles \

    --required \ tsconfig.app.json お問い合わせ Form \ > src/generated/jsonschema/model.json
  6. JSON Schema
 1 1 { "$schema": "http://json-schema.org/draft-07/schema#", "properties": { "お問い合わせの種類

    ": { "enum": [ "ご要望", "ご質問", "その他" ], "title": "お問い合わせの種類 ", "type": "string" }, "お問い合わせ内容 ": { "title": "お問い合わせ内容 ", "type": "string" }, "備考": { "title": "備考", "type": "string" }, "日中の連絡先 ": { "anyOf": [ { "properties": { "address": { "title": "address", "type": "string" }, ENUM
 ANY OF

  7. コンポーネントを実装 
 1 2 import { useState } from 'react';

    import { withTheme } from '@rjsf/core'; import type { RJSFSchema } from '@rjsf/utils'; import type { お問い合わせForm } from './model'; import validator from '@rjsf/validator-ajv8'; import formJson from '生成したpath; const Form = withTheme<お問い合わせForm, typeof schema>(Theme); function App() { const [data, setData] = useState<お問い合わせForm | null>(null); return ( <Form schema={formJson as unknown as JSONSchema7} validator={validator} onChange={(e) => e.formData && setData(e.formData)} onSubmit={(e) => e.formData && setData(e.formData)} /> ); } export default App; フォームが完成 !!!

  8. デザインの調整 
 1 6 Form
 UI Schema
 スタイルを定義
 JSON Schema


    データ構造を定義
 const uiSchema: UISchema = { // フォームの並び順 'ui:order': [ '氏名', 'お問い合わせの種類', 'お問い合わせ内容', '日中の連絡先', '備考' ], 日中の連絡先: { anyOf: [ { // type は固定なので表示しない type: { 'ui:widget': 'hidden' }, address: { 'ui:options': { label: false } }, }, { type: { 'ui:widget': 'hidden' }, number: { 'ui:options': { label: false } }, }, ], }, }; 実際はUI Schemaで
 デザインを調整が必要 

  9. 1 8 Pros
 • 記述量を大幅に減らすことができる 
 ◦ プロトタイプ作成に便利 !
 •

    型化しやすいので、デザインシステムなどと相性が良さそう 
 • 再帰的な構造を扱える 
 ◦ (JSON Schema の $ref)

  10. 1 9 cons
 • RJSF自体の学習コストが高い 
 • UI Schema や

    Custom Templates の概念・当て方に癖がある 
 ◦ 思い描いたレイアウトを実現するのに時間がかかることがある 
 • 集計値を表示するフィールドの実装が難しい 
 ◦ ex) FieldA の値は FieldB の値の1.10倍を自動入力