---
title: Implementation pattern of Tweeq
date: 2025-03-21T12:12:53.000Z
updated: 2026-01-08T14:50:44.581Z
url: https://baku89.com/Implementation_pattern_of_Tweeq
---

# Implementation pattern of Tweeq

- [Tweeq](/tweeq)

### Events

```
stateDiagram-v2
    [*] --> Focused:focus
    Focused --> Focused:update：modelValue
    Focused --> [*]:blur
```

### 原則

- `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`: 現在編集中の値を確定する

  - 典型的なコード
  - ```
    local.value = validLocal.value;
    display.value = print(validLocal.value);
    emit("confirm");
    ```

```
flowchart TB
    modelValue[modelValue: T]:::Model --> s{{≠ emittedModel?}}:::Cond -.->|decompose| local
    local[local: L]:::Local -->|"print"| display[display: string]
    display -->|"parse"| onInput{{onInput?}}:::Cond -.-> local
    local ==>|validate| validateResult
    validateResult([validated: ValidateResult&lt;L&gt;]):::Local --> p{{passed?}}:::Cond -.-> validLocal
    validLocal[validLocal: L]:::Local ==>|compose| emittedModel
    emittedModel([emittedModel]):::Model --> e{{≠ modelValue?}}:::Cond -->|update:modelValue| modelValue

    classDef Model fill:pink
    classDef Local fill:skyblue
    classDef Cond fill:white, stroke:gray
```

```
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`で状態を保持が保持されている

### 複数のインプットからなるインプットの実装

-
