react-jsonschema-formにて、JSON Schemaのexamplesキーワードを使ってみた

これは「react-jsonschema-formのカレンダー | Advent Calendar 2023 - Qiita」の17日目の記事です。

 
JSON Schemaでは、draft-06から examples キーワードが導入されました。draft-06のリリースノートには

array of examples with no validation effect; the value of "default" is usable as an example without repeating it under this keyword

JSON Schema - Draft-06 Release Notes

と記載されています。

また、Understanding JSON Schema のページにも

New in draft 6

The examples keyword is a place to provide an array of examples that validate against the schema. This isn't used for validation, but may help with explaining the effect and purpose of the schema to a reader. Each entry should validate against the schema in which it resides, but that isn't strictly required. There is no need to duplicate the default value in the examples array, since default will be treated as another example.

https://json-schema.org/understanding-json-schema/reference/annotations

と記載されています。

他に、JSON Schema Validationのページにも記載があります。

The value of this keyword MUST be an array. There are no restrictions placed on the values within the array. When multiple occurrences of this keyword are applicable to a single sub-instance, implementations MUST provide a flat array of all values rather than an array of arrays.

This keyword can be used to provide sample JSON values associated with a particular schema, for the purpose of illustrating usage. It is RECOMMENDED that these values be valid against the associated schema.

Implementations MAY use the value(s) of "default", if present, as an additional example. If "examples" is absent, "default" MAY still be used in this manner.

https://json-schema.org/draft/2020-12/json-schema-validation#name-examples

 
一方、RJSFは draft-07 対応にも関わらず、公式ドキュメントで examples キーワードに関する記載を見つけられませんでした。

RJSFでは examples キーワードはサポートされていないのかなと思っていたところ、 BaseInputTemplate.tsxソースコードにて以下の実装を見つけました。

// https://github.com/rjsf-team/react-jsonschema-form/blob/v5.15.1/packages/core/src/components/templates/BaseInputTemplate.tsx#L91

{Array.isArray(schema.examples) && (
  <datalist key={`datalist_${id}`} id={examplesId<T>(id)}>
    {(schema.examples as string[])
      .concat(schema.default && !schema.examples.includes(schema.default) ? ([schema.default] as string[]) : [])
      .map((example: any) => {
        return <option key={example} value={example} />;
      })}
  </datalist>
)}

これより、 examples キーワードは datalist タグの中で使われそうでした。

 
また、RJSFの型を見ても、 JSONSchema7 には examples というキーワードが存在していました。
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/json-schema/index.d.ts#L714

 
そこで、RJSFで examples キーワードを使った場合にどのような挙動になるか気になったことから、ためしてみることにしました。

 
目次

 

環境

  • react-jsonschema-form 5.15.0
  • React 18.2.0
  • React Router 6.20.1

 

JSON Schemaで examples キーワードを使い、表示してみる

BaseInputTemplate コンポーネントを使うため、 type = "text" な項目 stringInput を用意します。また、その項目に対して examples キーワードも使ってみます。

以下では examples として foobar を指定しています。

const schema: RJSFSchema = {
  title: "Examples Keyword Form",
  type: "object",
  properties: {
    stringInput: {
      type: "string",
      examples: ["foo", "bar"]
    }
  }
}

 
ただ、この定義をしたところ、JetBrainsのIDEでは

Initializer type {title: string, type: "object", properties: {stringInput: {examples: string[], type: "string"}}} is not assignable to variable type RJSFSchema

という型エラーになりました。

 
今回は型エラーを気にせず動かしてみたところ、HTML要素の datalist が表示されました。
: HTML データリスト要素 - HTML: ハイパーテキストマークアップ言語 | MDN

 
datalistから bar を選択すると、入力欄に bar が設定されました。

 
これより、RJSFで examples キーワードを使った場合、型エラーにはなるものの、画面表示のdatalistとしては正しく動いてそうと分かりました。

 

ソースコード

Githubにあげました。
https://github.com/thinkAmi-sandbox/rjsf_advent_calendar_2023

今回のプルリクはこちら。
https://github.com/thinkAmi-sandbox/rjsf_advent_calendar_2023/pull/15