Implementation pattern of Tweeq
Events
code:reactive.mmd
stateDiagram-v2
Focused --> Focused:update:modelValue
原則
update:modelValue: は自動的に発火させる
States that input components have internally
Types and States
modelValue: M: そのインプットのモデル値
display: string: UIとして表示する文字列
最大3回しか display.value = xxx というコードはコンポーネント内に登場しない
1. 非フォーカス時に外部からモデル値が変更された時
2. 直接インプットから編集されている時(display.value = e.target.value)
3.
local: Local: インプットが内部状態として持つ型
ModelとLocalは異なる可能性がある
e.g. InputColor(後述)
validateResult: ValidateResult<Local>: バリデーション結果。localよりautomatically computed
validLocal: Local | undefined: 最後にバリデーションに成功したlocalの値
Functions
print: Model -> string: モデル値をディスプレイ値に変換する
decompose: Model -> Local, compose: Local -> Model: モデル値とローカル値とを相互変換する
validate: Local -> Validator<Local>: ローカル値をバリデーションする
迷み!!!!
modelValue --> local 時にvalidateするかどうか
multiSelectのget/setValueにはlocalを渡すか、validLocalを渡すか
localってなに?
文字列による編集にせよ、
Actions
confirm: 現在編集中の値を確定する
典型的なコード
code:ts
local.value = validLocal.value
display.value = print(validLocal.value)
emit('confirm')
code:mmd
flowchart TB
modelValuemodelValue: T:::Model --> s{{≠ emittedModel?}}:::Cond -.->|decompose| local display -->|"parse"| onInput{{onInput?}}:::Cond -.-> local
local ==>|validate| validateResult
emittedModel(emittedModel):::Model --> e{{≠ modelValue?}}:::Cond -->|update:modelValue| modelValue classDef Model fill:pink
classDef Local fill:skyblue
classDef Cond fill:white, stroke:gray
code:states.mmd
stateDiagram-v2
modelValue --> local:decompose\n\n(if modelValue != emittedModel)
local --> display:print
display --> local: parse
local --> validated:validate (computed)
validated --> validLocal: set if validation doesn't fail
validLocal --> emittedModel: compose (computed)
emittedModel --> modelValue:update:modelValue\n\n(if modelValue != emittedModel)
classDef Model fill:pink
classDef Local fill:skyblue
class modelValue, emittedModel Model
class local, validated, validLocal Local
InputColor
表に出るコンポーネントはこういう風になっている(e.g. InputColor, InputColorPicker)
Model = string
Local = HSVA = {h: number, s: number, v: number, a: number}
その内側では、Model、LocalともにすべてHSVAで状態を保持が保持されている
複数のインプットからなるインプットの実装